算法设计课作业系列(2)
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.
解题过程
参考网址
白话经典算法系列之六 快速排序 快速搞定
注:以上的博客对于快速排序的解释较为容易理解,而这道题目的思想会借鉴到快排的思想,所以建议先学习并自行实现快排后再来解决这道题
思路分析
快排的思想大家都很熟悉,这道题也可以很简单地用快速排序去算出从大到小的序列然后求出第k个是多少,然而问题是我们有没有必要去全部排序一遍?
我们注意到快速排序的每一轮都会有一个基准,而在排序之后,这个基准所在位置左边都是比它小(大)的,而右边都是更大(小)的。因此,我们在每次的排序结束后,只需要判断基准所在的位置是在我们要的左边还是右边即可,之后再对半边进行排序即可。
因此思路就是,同样快排的步骤,不同的是,在每一轮排序完成后,若当前基准正好在k的位置,则返回,否则对左边或右边进行递归操作。
源代码
#include<vector>
using namespace std;
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
return findKthLargest(nums.begin(), nums.size(), k);
}
private:
int findKthLargest(vector<int>::iterator nums, int size, int k) {
if (size <= 1) {
return nums[0];
}
int flag = nums[0];
int front = 0;
int back = size - 1;
while (front < back) {
while (front < back && nums[back] <= flag) {
back--;
}
if (back <= front) {
break;
}
nums[front++] = nums[back];
while (front < back && nums[front] >= flag) {
front++;
}
if (back <= front) {
break;
}
nums[back--] = nums[front];
}
nums[front] = flag;
if (front == k - 1) {
return flag;
} else if (front > k - 1) {
return findKthLargest(nums, front, k);
} else {
return findKthLargest(nums + front + 1, size - front - 1, k - front - 1);
}
}
};