問題描述
輸入整數數組 ,找出其中最小的 個數。
:
arr = [3,2,1], k = 2
:[1,2] 或者 [2,1]
解題報告
- 方法一:堆
維護大小爲k的堆,當遍歷完數組時,輸出堆中的元素。
:,維護大小爲k的堆,複雜度爲,最壞情況下數組裏的 個數都會插入,所以時間複雜度一共是
: - 方法二:快速排序
藉助基準線,一次劃分之後,只需要處理其中一邊的元素。
:最好的情況:,最壞的情況:,每次的劃分點都是最大值或最小值,一共需要劃分 次,而一次劃分需要線性的時間複雜度。
:
實現代碼
- 堆
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
priority_queue<int>pq;
vector<int>ans(k);
if(k==0) return ans;
for(int i=0;i<k;i++){
pq.push(arr[i]);
}
for(int i=k;i<arr.size();i++){
if(pq.top()>arr[i]){
pq.pop();
pq.push(arr[i]);
}
}
for(int i=0;i<k;i++){
ans[i]=pq.top();
pq.pop();
}
return ans;
}
};
- 快速排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int n=arr.size();
if(n==k) return arr;
if(n<k || k<=0 || n==0) return vector<int>();
int l=0,r=n-1;
int index=partition(arr,l,r);
while(index!=k-1){
if(index>k-1) r=index-1;
else l=index+1;
index=partition(arr,l,r);
}
return vector<int>(arr.begin(),arr.begin()+k);
}
int partition(vector<int>&arr,int l,int r){
int temp=arr[l];
while(l<r){
while(l<r && arr[r]>=temp) r--;
arr[l]=arr[r];
while(l<r && arr[l]<=temp) l++;
arr[r]=arr[l];
}
arr[l]=temp;
return l;
}
};