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.
Example 1:
Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
My solution:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> nums_pq(nums.begin(), nums.end());
for (int i=0; i<k-1; ++i) {
nums_pq.pop();
}
return nums_pq.top();
}
};
Runtime: 16 ms, faster than 83.56% of C++ online submissions for Kth Largest Element in an Array.
Memory Usage: 10.7 MB, less than 9.59% of C++ online submissions for Kth Largest Element in an Array.
复习了一下priority queue的用法:
- pq可以pop可以push,可以top输出当前最大。
- pq可以用指针初始化
- pq默认是less对比,所以左侧top就是最大
- 如果要选最小,可以写
priority_queue<int, vector<int>, greater<int>()> nums_pq(nums.begin(), nums.end());
- 如果要选最小,可以写
改进版:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
if (k < nums.size()/2) {
priority_queue<int> nums_pq(nums.begin(), nums.end());
for (int i=0; i<k-1; ++i) {
nums_pq.pop();
}
return nums_pq.top();
}
else {
k = nums.size()-k+1; // 注意,这里是要+1,比如[3,2,1,5,6,4]第5大的是,第2小
priority_queue<int, vector<int>, greater<int>> nums_pq(nums.begin(), nums.end());
for (int i=0; i<k-1; ++i) {
nums_pq.pop();
}
return nums_pq.top();
}
}
};
Runtime: 12 ms, faster than 95.49% of C++ online submissions for Kth Largest Element in an Array.
Memory Usage: 10.7 MB, less than 9.59% of C++ online submissions for Kth Largest Element in an Array.
拓展:pq和heap的区别
https://www.geeksforgeeks.org/heap-using-stl-c/
https://www.fluentcpp.com/2018/03/13/heaps-priority-queues-stl-part-1/
Let’s consider the following heap (implemented as an array):
std::vector<double> numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::make_heap(begin(numbers), end(numbers));
// numbers is now {9, 8, 6, 7, 4, 5, 2, 0, 3, 1}
Removing the largest element
Finally, a priority queue needs to be able to remove its largest element with its pop method. The algorithm pop_heap moves the first element of the array to its end and rearranges the other elements into a heap:
std::pop_heap(begin(numbers), end(numbers)); // 9 is at the end
numbers.pop_back(); // 9 is gone, 8 is the new top
官方答案 O(N)
https://leetcode.com/problems/kth-largest-element-in-an-array/solution/
Approach 2: Quickselect
image.pngclass Solution:
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
def partition(left, right, pivot_index):
pivot = nums[pivot_index]
# 1. move pivot to end
nums[pivot_index], nums[right] = nums[right], nums[pivot_index]
# 2. move all smaller elements to the left
store_index = left
for i in range(left, right):
if nums[i] < pivot:
nums[store_index], nums[i] = nums[i], nums[store_index]
store_index += 1
# 3. move pivot to its final place
nums[right], nums[store_index] = nums[store_index], nums[right]
return store_index
def select(left, right, k_smallest):
"""
Returns the k-th smallest element of list within left..right
"""
if left == right: # If the list contains only one element,
return nums[left] # return that element
# select a random pivot_index between
pivot_index = random.randint(left, right)
# find the pivot position in a sorted list
pivot_index = partition(left, right, pivot_index)
# the pivot is in its final sorted position
if k_smallest == pivot_index:
return nums[k_smallest]
# go left
elif k_smallest < pivot_index:
return select(left, pivot_index - 1, k_smallest)
# go right
else:
return select(pivot_index + 1, right, k_smallest)
# kth largest is (n - k)th smallest
return select(0, len(nums) - 1, len(nums) - k)
网友评论