【第一周】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.
leetcode地址:https://leetcode.com/problems/kth-largest-element-in-an-array/description/
解题思路:
给出n个无序数,找出其中第k大的数。
最直接的想法是首先将数组排序,然后直接取第k个最大的数;不过其时间复杂度过高,sort()方法的时间复杂度为o(nlogn)。
我们并不需要整个排好序的数组;只需要在数组中找到某个数t,保证比t大的数为 k-1个,则t就是第k大的数。从这个思路可以联想到quicksort算法,可以利用其分块过程来解题。
quicksort的时间复杂度最好情况为o(n),最坏情况为o(n^2)。不过由于其最坏情况需要的条件非常苛刻,一般是不会出现这种极端情况的,其整体性能要优于将整个数组排序。
代码
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
if (nums.size() == 0) return -1;
if (nums.size() == 1) return nums[0];
int l = 0, r = nums.size()-1;
while(1) {
int pos = partition(nums, l, r);
if (k == nums.size() - pos) return nums[pos];
else if (k < nums.size() - pos) l = pos +1;
else r = pos -1;
}
}
int partition(vector<int>& nums, int l, int r) {
int pivot = nums[l];
int left = l+1, right = r;
while (left <= right) {
if (nums[left] > pivot && nums[right] < pivot) {
swap(nums[left], nums[right]);
left++;
right--;
}
if (nums[left] <= pivot) left++;
if (nums[right] >= pivot) right--;
}
swap(nums[l], nums[left -1]);
return left - 1;
}
};
总结
要熟练快排算法。最开始能够想到这种分治思路,不过由于快排比较难写,便直接新建两个数组来分隔大小部分;然而最后发现空间复杂度过高,提示Memory Limit;这表示所有数据操作只能在原vector上进行,最后只能重新复习快排算法。
关于此题还有其他实现方法;例如使用堆排序算法,维护一个大小为k的最大堆。不过这要用二叉树来实现,代码会更复杂难写一些。