【leetcode】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

二、补充知识:

快排的基本思想:
partition 分区函数会任意选择一个元素(该解法中选择最后一个元素arr[len-1])作为 mid(分区点),将数组中小于 mid 的点都放置到其左边,将大于mid的点都放置在其右边,最终 partition 函数返回 mid 的下标 i
经过这一步骤后,数组将分成3部分
1、arr[0] ~ arr[i-1] 都是不大于 mid 的元素
2、arr[i+1] ~ arr[len-1] 都是不小于 mid 的元素
3、arr[i] 是 pivot 元素

quick_sort(int[] arr, int low, int high) {
    if (low >= high) return;
    int i = partition(arr, low, high);
    quick_sort(arr, low, i-1);
    quick_sort(arr, i+1, high);
}

三、解题思路


使用快速排序思想,由于官方题解有点晦涩难懂,生成的partition随机位置难懂,因此结合了快速排序思想。给出了如下思路:
1、当partition的位置正好是第K大元素的位置,则直接返回mid。
2、当partition的位置<第K大元素的位置,则low=mid+1,即该元素的位置应该在mid的右边。
3、当partition的位置>第K大元素的位置,则high=mid-1,即该元素的位置应该在mid的左边。

三、代码

class Solution {
   public int findKthLargest(int[] nums, int k) {
		int len=nums.length;
		int kth=len-k;
		int low=0;
		int high=len-1;
		while(low<=high) {
			int mid=partition(nums,low,high);//mid存放每次partition的位置
			if(mid==kth) {//当partition的位置正好是第K大元素的位置,则直接返回mid
				return nums[mid];
			}else if(mid<kth) {//当partition的位置<第K大元素的位置,则low=mid+1,即该元素的位置应该在mid的右边
				low=mid+1;
			}else {//当partition的位置>第K大元素的位置,则high=mid-1,即该元素的位置应该在mid的左边
				high=mid-1;
			}
		}
		return nums[kth];
	}
	public int partition(int[] nums,int low,int high) {
		int i=low;//i用来记录当前<privor尾节点的位置
		int privor=nums[high];//默认nums[high]为privor
		//快排思想,所有小于privor的数移到privor的左边,大于privor的数移动到它的右边
		for(int j=low;j<high;j++) {
			if(nums[j]<privor) {
				swap(nums, i, j);
				i++;
			}
		}
		//最后i指向的是privor的最终位置
		swap(nums,i,high);
		return i;
	}
	//交换两个数
	public void swap(int[] nums,int i,int j) {
		int temp=nums[i];
		nums[i]=nums[j];
		nums[j]=temp;
	}
}

四、运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雨碎江南 Lucinda

如果您喜欢这篇文章欢迎打赏支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值