栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

力扣 215. 数组中的第K个最大元素C++代码及分析

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣 215. 数组中的第K个最大元素C++代码及分析

力扣 215. 数组中的第K个最大元素 题目

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例1:

输入: [3,2,1,5,6,4], k = 2
输出: 5

示例2:

输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
分析

偷懒方法很多,可以直接sort后输出n-k位置的元素,也可以用priority_queue声明一个大顶堆弹出k-1个元素,堆顶元素即为答案。
不过这个题目主要是考察快速排序,官方题解给的比较乱,给出一个我认为看的比较懂的

代码
class Solution {
public:
	int QuickSort(vector &nums, int begin, int end, int target) {
	    if (begin >= end)
	        return nums[end];
	    int i = begin;
	    int j = end;
	    int index = rand() % (end - begin);
	    swap(nums[begin], nums[begin + index]);
	    int tmp = nums[begin];
	    while (i != j) {
	        while (j > i && nums[j] >= tmp) {
	            --j;
	        }
	        while (j > i && nums[i] <= tmp) {
	            ++i;
	        }
	        if (i != j)
	            swap(nums[i], nums[j]);
	    }
	    swap(nums[begin], nums[i]);
	    if (i == target)
	        return nums[i];
	    if (target < i)
	        return QuickSort(nums, begin, i - 1, target);
	    else
	        return QuickSort(nums, i + 1, end, target);
	}
	
	int findKthLargest(vector &nums, int k) {
	    return QuickSort(nums, 0, nums.size() - 1, nums.size() - k);
	}
};

时间复杂度为O(log n),因为每次只需要遍历一半的空间,另外一半不需要进行排序

代码解释及分析

代码不难懂,基本上懂了快速排序的原理都可以看懂,主要解释几个可能会产生疑惑的地方:

	    int index = rand() % (end - begin);
	    swap(nums[begin], nums[begin + index]);

因为快速排序只有随机选择基准节点时复杂度才为O(nlog n),所以这个地方需要生成随机数来负责基准节点的选取,为了代码的方便编写,随机选取了基准节点后可以直接和begin位置的节点进行交换即可,在912. 排序数组这个题目中也可以得到验证,直接选取begin位置的节点作为哨兵节点时是会进行超时的(或者运行时间会长很多),只有随机选择节点才能 通过。

为什么外层的while循环体内部还需要判断一次i != j并进行交换

	        while (j > i && nums[j] >= tmp) {
	            --j;
	        }
	        while (j > i && nums[i] <= tmp) {
	            ++i;
	        }
	        if (i != j)
	            swap(nums[i], nums[j]);

观察这段代码的两个while条件的判断,什么情况下会出现 i != j,只有当num[j] < tmp和nums[i] > tmp的时候,这个时候两个哨兵节点是还没有相交的,还需要继续走,这个时候就可以将num[i]和num[j]进行交换,那样位置i的节点就会小于tmp,同理位置j的节点会大于tmp,这个时候两个哨兵节点就可以继续往中间走了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1033888.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号