Kth Largest Element in an Array
https://leetcode.com/problems/kth-largest-element-in-an-array/description/
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.
Thoughts
是找第k大的,因此是倒序。
Partition: 把pivot放到应置的位置并返回对应的位置。用双头指针通过swap把比它大的放前面,剩下的放后面。
通过每次返回的排好的位置pos和K作比较,此时pos前或pos后的都比K小或大从而(类似二分法)调整双头指针(start和end)位置抛去pos前或后部分再做partition. 直到pos刚好==k - 1。
Code
/*
* @lc app=leetcode id=215 lang=cpp
*
* [215] Kth Largest Element in an Array
*/
// @lc code=start
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
const auto partition = [&](int l, int r) {
swap(nums[l], nums[rand() % (r - l + 1) + l]);
const auto s = l, t = nums[l++];
while (l <= r) {
if (nums[l] > t) ++l;
else if (nums[r] <= t) --r;
else {
swap(nums[l++], nums[r--]);
}
}
swap(nums[s], nums[r]);
return r;
};
int start = 0, end = nums.size() - 1;
--k;
while (true) {
int pos = partition(start, end);
if (pos == k) return nums[pos];
else if (pos < k) start = pos + 1;
else end = pos - 1;
}
return nums[0];
}
};
// @lc code=end
Analysis
平均来说, 每次partition把原数组分成了前后各一半(pos == mid), 下次搜索时问题规模减半, 因此T(n) = T(n/2) + O(n) , O(n) 用于partition, 时间复杂度O(N). 最差时每次partition只能减1个问题规模(逆序时), 时间复杂度O(N^2).
Ver.2
还可以用heap sort做, 维持大小为k的min heap, 此时heap中顶元素即第k大.
Last updated
Was this helpful?