[算法积累] [leetcode] [排序] [3] 求第k大算法 C++

1.暴力

直接使用sort

sort(arr.begin(),arr.end());

2.堆/优先级队列

依次弹出即可,这种方法也适合求第k个最大的元素,且要求每个元素都不相同。

	int num = 0;
	vector<int> res(k, 0); //初始化为有k个空间,默认值为0的数组
	if(k == 0) return res;
	priority_queue<int,vector<int>,greater<int>> q;//greater也就意味着大的在后面
	for(auto item:arr) q.push(item);
	
	while(!q.empty() && num < k){
	    res[num] = q.top();
	    q.pop();
	    num++;
	}
	return res;

3.快速排序变种

//这里使用覆盖的方法(自己起的,另外一个是交换)
int Partition(vector<int> &arr,int left,int right){
        if(left == right) return left;
        //以最左边作为中轴,此时的中值就是tmp
        int tmp = arr[left];
        while(left < right){
        	
            while(left < right && arr[right] >= tmp) right--;
            //右边存在比中值大的,将其放到左边。
            arr[left] = arr[right];
            while(left < right && arr[left] <= tmp) left++;
            //左边存在比中值小的,将其放到右边。
            arr[right] = arr[left];
        }
        arr[left] = tmp;
        //返回最后的分界点
        return left;
    }

	//递归实现
    void quicksort(vector<int> &arr,int left,int right,int k){
        if(left < right){
            int pos = Partition(arr,left,right);
            //如果中轴在k处,直接返回
            if(pos == k) return;
            quicksort(arr,left,pos-1,k);
            quicksort(arr,pos+1,right,k);
        }

    }   
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        vector<int> res(k,0);
        quicksort(arr,0,arr.size()-1,k);
        for(int i = 0;i<k;i++) res[i] = arr[i];
        return res;


    }

4.nth_element

nth_element(arr.begin(), arr.begin() + k, arr.end(),cmp);

不保证前一段和后一段有序
nth_element

5.Hash

在数值不大的时候,可以使用hash的方式进行存储,之后依次读即可。这个也适用于求第k大,但是每个元素不同的情况.

        int num = 0;
        map<int,int> m;
        vector<int> res(k,0);
        for(int i = 0;i<arr.size();i++){
            m[arr[i]]++;
        }
        for(auto item:m){
        	//需要注意,要每次将数字减一
            while(item.second > 0){
                if(num >= k) break;
                res[num++] = item.first;
                item.second--;
            }
        }
        return res;

6.总结

其实都差不多,总体上就两个思路,快排和hash。其他都是这两个衍生出来的。正常情况下,直接怼快排即可。因为其时间复杂度低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值