從 n個長度的序列中找出前 m大個元素

2021-08-21 08:36:07 字數 1809 閱讀 5345

方法一

利用優先佇列的特性(堆序), 在構建出 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位置...