描述
給定乙個陣列包含n個元素,統計前m大的數並且把這m個數從大到小輸出。輸入
第一行包含乙個整數n,表示陣列的大小。n < 100000。輸出第二行包含n個整數,表示陣列的元素,整數之間以乙個空格分開。每個整數的絕對值不超過100000000。
第三行包含乙個整數m。m < n。
從大到小輸出前m大的數,每個數一行排序後再輸出,複雜度 o(nlogn)
用分治處理:複雜度 o(n+mlogm)
思路
把前m大的都弄到陣列最右邊,然後對這最右邊m個元素排序,再輸出
引入操作 arrangeright(k): 把陣列(或陣列的一部分)前k大的一:都弄到最右邊
如何將前k大的都弄到最右邊二:1)設key=a[0], 將key挪到適當位置,使得比key小的元素都在
key左邊,比key大的元素都在key右邊(線性時間完成)
2) 選擇陣列的前部或後部再進行 arrangeright操作
選擇陣列的前部或後部再進行 arrangeright操作關鍵a = k done
a > k 對最右邊a-1個元素再進行arrangerigth(k)
a < k 對左邊b個元素再進行arrangeright(k-a)
o(n)時間內實現把前m大的都弄到陣列最右邊
t(n) = t(n/2) + an以上思路來自北大郭偉老師= t(n/4) + an/2 + an
= t(n/8) + an/4 + an/2 + an
= …= t(1) + … + an/8 + an/4 + an/2 + an
< 2an
即 o(n)
**
#include
#include
using
namespace std;
#define n 10000+5
int a[n]
;int b[n]
;int n, m;
bool
compare
(int x,
int y)
void
arrangeright
(int l,
int r)
} j--
;swap
(a[j]
, a[l]);
if(n - j == m)
return
;else
if(n - j < m)
arrangeright
(l, j-1)
;else
if(n - j > m)
arrangeright
(j+1
, r);}
intmain()
分治法 前m大的數
給定乙個陣列包含n個元素,統計前m大的數並且把這m個數從大到小輸 出如果先排序再找前m大的,時間複雜度為o nlogn 用分治處理 複雜度 o n mlogm 思路 把前m大的都弄到陣列最右邊,然後對這最右邊m個元素排序,再輸出 關鍵 o n 時間內實現把前m大的都弄到陣列最右邊 如何將前k大的都弄...
輸出前m大的數
o n mlogm n為快排中線性掃瞄時間,mlogm為對m各最大數進行歸併排序耗時 includeusing namespace std int a 100 void swap int a,int b void merge int a,int s,int m,int e,int tmp 歸併 把每...
輸出前m大的數
描述 給定乙個陣列包含n個元素,統計前m大的數並且把這m個數從大到小 輸出。輸入 第一行包含乙個整數n,表示陣列的大小。n 100000。第二行包含n個整數,表示陣列的元素,整數之間以乙個空格分開 每個整數的絕對值不超過100000000。第三行包含乙個整數m。m n。輸出從大到小輸出前m大的數,每...