zl程序教程

您现在的位置是:首页 >  其他

当前栏目

选取TOP K的问题之快速排序

2023-04-18 15:22:16 时间

方法1:快速排序:

  1. 哨兵划分:选取一个哨兵,将大于哨兵的移到哨兵右侧;小于哨兵的移到哨兵左侧。
  2. 递归操作:递归的将左右子数组进行哨兵划分,直至区间长度为1,完成递归。
  3. 快排完成后将数组前k个值输出
    void quicksort(vector<int>&arr,int l,int r){
        if(r<=1) return;
        int i = l;int j = r;
        while(i<j){
            while(i<j && arr[j] >= arr[l]) --j;
            while(i<j && arr[i] <= arr[l]) ++i;
            swap(arr[i],arr[j]); 
        }
        swap(arr[l],arr[i]);
        quicksort(arr,l,i-1);
        quicksort(arr,i+1,r);
    }

l和r是数组的左右边界;

时间复杂度:O(Nlog N); 空间复杂度:O(log N)最好;O(N)最坏

方法2:基于快速排序的数组划分

核心思想:因为返回的值不要求排序,只需要找出最小的前k个值就行。所以不再对左右两个子数组都进行递归操作,而是根据 k的值 与每次递归之后的 i值进行比较,若大于i,则说明前 第 k+1 个最小值在右子数组,小于i,则说明 第k+1个最小值在左子数组,若相等,则说明是 arr[k]即为第k+1个最小值,直接返回前k个值。

class{
public:
    vector<int> getLeastNumbers(vector<int>&arr,int k){
        if(k>=arr.size()) return arr;
        return quicksort(arr,k,0,arr.size()-1);
    }
private:
    vector<int> quicksort(vector<int>& arr,int k,int l ,int r){
        int i = l, j = r;
        while(i<j){
            while(i<j && arr[j] >= arr[l]) --j;
            while(i<j && arr[i] <= arr[l]) ++i;
            swap(arr[i],arr[j]);
        }
        swap(arr[i],arr[l]);
        if(k > i) return quicksort(arr,k,i+1,r);
        if(k < i) return quicksort(arr,k,l,i-1);
        vector<int>v;
        v.assign(arr.begin(),arr.begin()+k);
        return v;
    }
};

 时间复杂度:等比数列求和,O(N); 空间复杂度:O(log N)。