演算法-十億數字中找出最大的一萬個--9-3
阿新 • • 發佈:2019-02-14
十億的資料量 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;
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;