問題描述:給定的n個整數,計算其中最小的k個數。
最直觀的解法莫過於將n個數按公升序排列後輸出前k個。但是就效率來看,這種方法並不是最理想的。一種改進方法是借助快速排序中對陣列的劃分,以第k個元素對陣列進行劃分,使得比第k個數字小的數字都在其左邊,比其大的數字都在它的右邊。
void swap(int &a, int &b)
int partition(int data, int length, int start, int end)
} ++index;
swap(data[index], data[end]);
return index;
}void getkleastnumbers(int data, int length, int result, int k)
for(int i = 0; i < k; ++i)
result[i] = data[i];
}
通過分析可以確定演算法的時間複雜度是o(n),是一種比較高效的解法。但是上述演算法存在的問題是修改了原始陣列資料,因此在不允許修改原始資料的情況下的應用就會受到限制。
在不修改原始資料的前提條件下,我們可以建立乙個大小為k的容器存放最小的k個數。再對n個整數進行遍歷,如果容器中的數少於k個,則直接把讀入的數存入容器;如果容器中的數大於等於k個,同時當前讀入的數小於容器中最大的數,那麼刪除容器中最大的數,將該數讀入容器,否則不做操作。為了確保快速刪除容器中最大的數,容器資料的儲存可以考慮使用最大堆。由於最大堆的根結點的值大於它的子樹中任意結點的值,因此可以在o(1)得到已有k個數中的最大者,刪除和插入操作的時間則為o(lgk)。對n個數重複最大堆的插入、刪除操作總的演算法時間複雜度為o(nlgk)。下面是使用stl multiset完成上述演算法的實現**。
//建立最大堆儲存最小的k個數
void getkleastnumbers(const int data, int length, multiset> &result, int k)
} }}
上述兩種方法都實現求最小k個數,雖然第二種方法比第一種方法慢一些,但是它並不修改原始資料,另外比較適用於海量資料處理的情形。因此兩種方法各有優劣,實際應用時視具體情況確定演算法的選用。
最小的K個數
從 陣列中出現次數超過一半的數字 得到啟發,同樣可以基於partition函式來解決。一 o n 演算法 void getleastnumbers int input,int n,int output,int k else for int i 0 i k i output i input i 二 o...
最小的K個數
輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,如果不讓使用sort的話,自己實現乙個,或者依次選取最小的 class solution public vectorgetleastnumbers solution vectori...
最小的K個數
輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,基本方法 思路一 在k個數的陣列中多次排序,每次替換掉最大的,直到原陣列中的數比較完 vectorgetleastnumbers solution vectorinput,int ...