1. 程式人生 > >演算法-十億數字中找出最大的一萬個--9-3

演算法-十億數字中找出最大的一萬個--9-3

十億的資料量    4G記憶體空間
1.建陣列  迴圈一萬次 找出最大的一萬個
  複雜度o(n*m) n為10億  m為1萬


2.藉助快速排序   
複雜度o(nlogn)


3.不想放入記憶體 佔據如此大的空間
建一個長度為1萬的陣列    將前1萬個數字放入陣列   其餘數  遍歷10億 比較每一個和陣列中的最小數的大小  小則不管 大則替換插入  


4.大頂堆
建一個空間為1萬的堆(小頂堆) 堆頂是最小數字 每次讀取一個 數字 判斷堆 是否已滿  。  判斷數字是否大於堆頂元素  如果大於  則刪除 插入新元素 。插入時會重建堆。重建複雜度為o(logn)   .效能好很多 所以現在時間複雜度為  o((n-m)*logm)  效能已經達到最優


 --找出 陣列中第K大的數
時間複雜度為o(n)  空間複雜度為o(1)
//核心程式碼
int all=(1+100)*100/2
for(int i=0;i<array.length;i++){
all-=array[i];
}
sysout("缺失數字為"+all);


//核心程式碼


int i=partition(array,begin,end);
if(i+1>k){
find(array,begin,i-1,k);
}else if(i+1<k){
find(array,i+1,end,k);
}else{
sysout("找到了"+array[i]);


return;
}


//partition方法


if(begin<end){
int key=array[begin];
while(begin<end){
while(begin<end && array[end]>key){
end--;
}
if(begin<end){
array[bagin]=array[end];
begin++;
}
while(begin<end && array[end]<key){
begin++;
}
if(begin<end){
array[end]=array[begin];
end--;
}
}
array[begin]=key;
}
return begin;