Leetcode 面試題40. 最小的k個數【最大堆&快排】

問題描述

輸入整數數組 arrarr,找出其中最小的 kk 個數。
輸入
arr = [3,2,1], k = 2
輸出:[1,2] 或者 [2,1]

解題報告

  • 方法一:堆
    維護大小爲k的堆,當遍歷完數組時,輸出堆中的元素。
    時間複雜度O(nlogk)O(n\cdot log k),維護大小爲k的堆,複雜度爲O(logk)O(logk),最壞情況下數組裏的 nn 個數都會插入,所以時間複雜度一共是 O(nlogk)O(n\cdot logk)
    空間複雜度O(k)O(k)
  • 方法二:快速排序
    藉助基準線,一次劃分之後,只需要處理其中一邊的元素。
    時間複雜度:最好的情況:O(k)O(k),最壞的情況:O(nk)O(nk),每次的劃分點都是最大值或最小值,一共需要劃分 kk次,而一次劃分需要線性的時間複雜度。
    空間複雜度O(logn)O(logn)

實現代碼

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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章