kth-largest-element-in-an-array_leetcode

本文深入讲解了一种基于快速排序思想的快速选择算法,用于寻找数组中第k大的元素。通过对比两种实现方式,阐述了算法的基本原理、关键步骤及易错点,帮助读者理解并掌握该算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题用了快排的思想,思路如下:

数组从小到大排序思想更为直观,所以一开始先k = n-k

1)选一个pivot,然后把pivot放在合适的位置,也就是快排的Partion操作,把小于pivot的放前面,大于pivot的放后面。

2)如果pivot的位置等于k,则返回pivot

3)如果pivot的位置大于k,则证明要找的数在pivot前面,否则在后面,然后递归就可以了。

特别的,如果left == right,直接返回就可以,也不用找pivot了

 

这里的下标非常容易出错,有两个版本:

第一个版本

class Solution {
public:
    int find(vector<int> &nums, int left, int right, int k){
        if(left == right)
            return nums[left];
        int i = left, j = right;
        int pivot = nums[left];
        while(i < j){
            while(nums[i] <= pivot && i < right) i++;
            while(nums[j] > pivot && left < j) j--;
            if(i < j){
                int tmp = nums[i];
                nums[i] = nums[j];
                nums[j] = tmp;
            }
        }
        int ind = j;
        
        int tmp = nums[ind];
        nums[ind] = nums[left];
        nums[left] = tmp;
        if(ind == k){
            return nums[ind];
        } else if(ind > k){
            return find(nums, left, ind - 1, k);
        } else {
            return find(nums, ind + 1, right, k);  
        }
    }
    int findKthLargest(vector<int>& nums, int k) {
        return find(nums, 0, nums.size() - 1, nums.size() - k);
    }
};

第二个版本

class Solution {
public:
    int find(vector<int> &nums, int left, int right, int k){
        if(left == right)
            return nums[left];
        int i = left + 1, j = right;
        int pivot = nums[left];
        while(i != j){
            while(nums[i] <= pivot && i < j) i++;
            while(nums[j] > pivot && i < j) j--;
            if(i != j){
                int tmp = nums[i];
                nums[i] = nums[j];
                nums[j] = tmp;
            }
        }
        int ind = (nums[i] > pivot) ? i - 1 : i;
        
        int tmp = nums[ind];
        nums[ind] = nums[left];
        nums[left] = tmp;
        if(ind == k){
            return nums[ind];
        } else if(ind > k){
            return find(nums, left, ind - 1, k);
        } else {
            return find(nums, ind + 1, right, k);  
        }
    }
    int findKthLargest(vector<int>& nums, int k) {
        return find(nums, 0, nums.size() - 1, nums.size() - k);
    }
};

可以看到, i和j的含义都不一样,但是最后都能得到正确的答案。我认为第二种比较直观。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值