方法一
利用優先佇列的特性(堆序), 在構建出 max堆(大頂堆)之後, 不斷將堆頂的元素移除, 就能很輕鬆的獲取前 m個最大的元素.
方法二
對第一種方法的優化, 維護乙個含有 m個元素的序列, 在對原始數列進行掃瞄, 動態調整目標序列, 一次掃瞄結束之後, 前 m個元素也就找到了.
public
class
sortdemo ;
printarr(findmaxm(arr, 3));
printarr(findmaxm_2(arr, 3));
}// 方法一:
// 從給定序列中找出前 m個最大的元素 主例程
private
static
int findmaxm(int arr, int m)
system.arraycopy(arr, arr.length - m, result, 0, m);
return result;
}// 方法二:
// 維護乙個 m個大小的堆, 在對原始陣列的掃瞄中, 動態調整堆, 掃瞄完成即找到前 m個元素
private
static
int findmaxm_2(int arr, int m)
// 對堆中元素進行排序
// 起始這一步也可以不要, 並沒有要求前 m大個元素的順序
deletemax(result);
return result;
}private
static
intfindmin(int arr)
}return min;
}private
static
intfindminindex(int arr)
}return index;
}// build max heap
private
static
void
buildmaxheap(int arr)
}// delete max
private
static
void
deletemax(int arr)
}// 下濾操作
private
static
void
percolatedown(int arr, int i, int n)
// 將需要被調整的節點與其子節點進行比較, 如果小於子節點, 當前節點的值替換為子節點的值 (注意不是交換)
if (tmp < arr[child]) else
}// 找到合適的位置後, 直接賦值來避免多餘的交換操作
// 注意 i值的變化, 在調整位置過程中, 如果改變了子串行的堆序, 也要立即調整過來
arr[i] = tmp;
}// 獲取指定節點處元素的左節點索引
private
static
intleftchild(int i)
// 交換陣列中兩個元素的位置
private
static
void
swap(int arr, int i, int j)
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}// 列印陣列元素
private
static
void
printarr(int arr)
}
找出m個總和為n的數字
上周末公司組織去旅遊,在路上乙個同事提出了乙個小問題,就是怎麼找出三個數,使它們的和為13。後來又引申為如何找出m個數,使它們的和為n。下面是使用遞迴的方法來實現 import sysdef test nblock,ntotal,nbegin 1 if nblock 1 return ntotal ...
從M個數中選擇前N大的數
如果對m個數字全排列,1 用簡單排序演算法,例如氣泡排序,時間複雜度m m 2 用快速排序 最壞時間複雜度度蛻化為m m 堆排序歸併排序 平均時間負責度為m logm 此處,需要選擇前n大的數,用氣泡排序,迴圈次數為n,時間複雜度為m n 如果是海量資料呢?筆試時經常碰到這樣類似的題目 從100w個...
從n個無序數中找出第K大的數
n個無序數中求第k大數 include include include using namespace std 氣泡排序思想,時間複雜度 o n k int findk 2 int a,int k return a k 1 堆排序思想,時間複雜度 o nlogk 將a s.m 調正為堆,其中除s位置...