LeetCode 之 数组中的第K个最大元素(一)

题目要求给出数组中第 k 大的元素,我最直接的想法就是对整个数组进行排序,然后返回数组中第 k 大的元素。
在这里插入图片描述

1. 冒泡排序

要想完成对数组 nums 的排序,冒泡排序需要进行 nums.size() - 1 轮排序,因为最后一个元素无需进行排序。冒泡排序每轮排序都会将待排数组中的最大值放到数组的末尾。

因此,要想找到数组中第 k 大的元素,只需进行 k 轮排序。
冒泡排序可以从小到大排序(正序),也可以从大到小排序(倒序)。
下面分别介绍正序和倒序实现。

1.1 从小到大的冒泡排序

如果采用从小到大的原则进行排序,nums.size() - 1 为数组最后的元素,也是数组中的最大值。那么第 k 大的元素在数组中的第 nums.size() - k 位上。

冒泡排序采用双层循环,内层循环为一趟排序,外层循环为 k 趟排序。第 k 趟排序后,数组索引 nums.size() - k 上为数组中第 k 大的元素。
算法的时间复杂度为 O(n²) ,还有很大的优化空间,因此可以考虑时间复杂度较低的快速排序。

class Solution {
   
   
public:
    int findKthLargest(vector<int>& nums, int k) {
   
   
        for(int last_position = nums.size() - 1; last_position >= nums.size() - k; last_position--)
        {
   
   
        	// 设置标准位,优化最坏情况(整个数组都是逆序的)
            int flag = 0;
            for(int i = 0; i < last_position; i++)
            {
   
   
                if(nums[i] > nums[i + 1])
                {
   
   
                    swap(nums[i], nums[i + 1]);
                    flag = 1;
                }
            }
            // 如果一趟排序后,没有发生任何元素交换,说明数组已经是有序的,直接退出即可
            if(flag == 0)   break;
        }
        // 返回第 k 大的元素
        return nums[nums.size() - k];
    }
};

1.2 从大到小的冒泡排序

采用从大到小的原则进行排序,那么数组的最大值就在数组的首位,数组索引为 0 。因此,第 k 大的元素在数组中的索引为 k - 1 。最后返回 nums[k - 1] 。

class Solution {
   
   
public:
    int findKthLargest(vector<int>& nums, int k) {
   
   
        for(int last_position = nums.size() - 1; last_position >= k - 1; last_position--)
        {
   
   
            for(int j = 0; j < last_position; j++)
            {
   
   
                if(nums[j] < nums[j + 1])
                {
   
   
                    swap(nums[j], nums[j + 1]);
                }
            }
        }
        return nums[k - 1];
    }
};

2. 快速选择排序

快速选择排序是快速排序的升级版,快速排序需要递归 选取主元 左边的数组 和 选取主元 右边的数组。但是,我们的目的不是给整个数组排序,而是找到数组中第 k 大的元素,那么我们还需要同时递归主元的左右两侧的数组吗?

快速排序首先会选定主元,然后将主元放到数组中合适的位置,即主元左边的元素都小于主元,主元右边的元素都大于主元(采用从小到大排序)。一般用 partition 函数来完成放置主元的任务。调用 partition 函数后主元就被排好序了,之后不会再改变位置了。

利用这个特性,我们可以比较数组中第 k 大元素与主元位置间的关系。注意此处所说的数组中第 k 大元素指的是排好序后第 k 大元素所在的位置。
当二者相等时,说明主元就是数组中第 k 大元素,直接返回主元即可。
当主元位置大于数组中第 k 大元素时,说明当前的主元

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值