算法课第16周第1题—— 215. Kth Largest Element in an Array

题目描述:

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note: 
You may assume k is always valid, 1 ≤ k ≤ array's length.


程序代码:

class Solution {
public:
	// 用于分治算法的函数,将数组分割
	int par(vector<int>& nums, int low, int high) {
		// 题意中k绝对有效,所以不用考虑无效问题
		// 取第一个数(为了方便)为枢v
		int v = nums[low];
		// 将所有大于枢v的数放到v左边,小于v的放到v右边
		while (high > low) {
			while (high > low && nums[high] <= v) {
				high--;
			}
			// 和下面一起起到swap的作用
			nums[low] = nums[high];

			while (high > low && nums[low] >= v) {
				low++;
			}
			nums[high] = nums[low];
		}
		nums[low] = v;
		// 返回枢v所在的位置
		return low;
	}

	// 寻找第k大数的函数
	int findKthLargest(vector<int>& nums, int k) {
		int low = 0;
		int high = nums.size() - 1;
		
		// 用循环替代递归,防止空间复杂度过大
		while (true) {
			// 枢的位置pos
			int pos = par(nums, low, high);
			// k在枢左边
			if (k < pos + 1) {
				high = pos - 1;
			}
			// 循环直到枢的位置和k一致(注意有差一个1)
			else if (k == pos + 1) {
				return nums[pos];
			}
			// k在枢右边
			else {
				low = pos + 1;
			}
		}
	}
};


简要题解:

这周开始复习前面的内容,因此选了这题分治算法的题目来做。

先理解题意。本题输入为一串数组和一个数k,要求找出数组中第k大的数并输出。(假设k有效)

本题类似课上所讲到过的selection问题,我选做这题算是对这类问题的一个练习和复习。用分治算法处理这种问题时,可以取出一个数v作为枢,然后将数组分为三组,即小于v的部分,等于v的部分,大于v的部分。当枢v的位置pos与k相等时(可能由于数组的处理原因差一个1,且这里数组需要枢左边的数比枢大,右边比枢小),这个位置的元素nums[pos]即可作为输出;否则,用循环或递归的方法从这剩余两组中再进一步细化找出最终的输出。

其实这种分治算法类似快速排序的处理方法,因此我在写代码时参考了快速排序算法的写法。用一个par函数作为将数组分割的函数,传入的参数有数组nums, 左端标low,右端标high。取数组中第一个数为枢v(这里只是为了方便所以取第一个数),接着可以用循环将小于v的数都交换到v的右边,大于v的数都交换到v的左边。函数par最终返回v的位置。在findKthLargest函数中,则用循环的方法,判断k与pos之间的位置关系,根据之前所提到的方法最终找到输出。需要注意的是,理论上用递归的方法也可以,不过本题中我尝试用递归方法导致了空间复杂度过高,因此我采用了循环的方法。

此外本题直接用stl库中的sort方法可以很简单的得出答案,不过就没有用到分治算法了,因此这里不提。

通过本题我重新复习了一下分治算法。接下来我还会对之前所做的一些算法类型的题目类型进行复习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值