LeetCode 215. Kth Largest Element in an Array
https://leetcode.com/problems/kth-largest-element-in-an-array/
Medium
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.
- 数组排序题。
- 第一种解法,最简单的用STL sort排序,因为是升序排列,所以nums[n - K]就是第K大的元素。
- sort - C++ Reference
- http://www.cplusplus.com/reference/algorithm/sort/
- sort - C++ Reference
- 第二种解法,用快排中的分治方法。因为快排中每一趟排序之后能找出第pos大的元素,所以K趟排序就能找出第K大的元素。按照从大到小排序,一趟排序之后,如果pos < K,那么Kth在pos右边区间,反之则在pos左边区间。时间复杂度O(N),最坏情况在已经排好序的情况下为O(N^2)。
- [Data Structure & Algorithm] 八大排序算法 - Poll的笔记 - 博客园
- http://www.cnblogs.com/maybe2030/p/4715042.html#_label5
- [Data Structure & Algorithm] 八大排序算法 - Poll的笔记 - 博客园
- 第三种解法可以用STL priority_queue。因为优先队列实际上用到了最大堆,默认情况下top返回最大元素,K次循环就可以找到第K大的元素。
- priority_queue - C++ Reference
- http://www.cplusplus.com/reference/queue/priority_queue/
- priority_queue - C++ Reference
- 第四种解法可以用STL multiset。多元集合默认情况下按升序排列,所以维护一个K个元素的集合,begin()就是第K大的元素。
- multiset - C++ Reference
- http://www.cplusplus.com/reference/set/multiset/
- multiset - C++ Reference
- 第五种解法可以用堆排序。
- Kth Largest Element in an Array - LeetCode
- https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60309/4-C++-Solutions-using-Partition-Max-Heap-priority_queue-and-multiset-respectively
- Kth Largest Element in an Array - LeetCode
1 // 2 // main.cpp 3 // LeetCode 4 // 5 // Created by Hao on 2017/3/16. 6 // Copyright © 2017年 Hao. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <vector> 11 #include <queue> 12 #include <set> 13 using namespace std; 14 15 class Solution { 16 public: 17 // STL sort 18 int findKthLargest(vector<int>& nums, int k) { 19 sort(nums.begin(), nums.end()); // STL sort in ascending order 20 return nums.at(nums.size() - k); 21 } 22 23 // Divide and Conquer 24 int findKthLargest2(vector<int>& nums, int k) { 25 int l = 0, r = nums.size() - 1; 26 27 while (true) { 28 int pos = partition(nums, l, r); // one time quick sort 29 30 if (pos == k - 1) // the k-th largest key 31 return nums.at(k - 1); 32 else if (pos < k - 1) // in the right partition of pos 33 l = pos + 1; 34 else // in the left partition of pos 35 r = pos - 1; 36 } 37 } 38 39 int partition(vector<int> & nums, int left, int right) { 40 int i = left, j = right, pivot = nums.at(left); // pivot key 41 42 while (i < j) { 43 while (i < j && nums.at(j) <= pivot) -- j; // scan from right to left 44 if (i < j) nums.at(i ++) = nums.at(j); // place nums[j] 45 46 while (i < j && nums.at(i) >= pivot) ++ i; // scan from left to right 47 if (i < j) nums.at(j --) = nums.at(i); // place nums[i] 48 } 49 50 nums.at(i) = pivot; // place pivot key - the (i+1)-th largest key 51 52 return i; 53 } 54 55 // priority_queue 56 int findKthLargest3(vector<int>& nums, int k) { 57 priority_queue<int> pq(nums.begin(), nums.end()); 58 59 for (int i = 0; i < k - 1; i ++) 60 pq.pop(); // remove k-1 largest elements 61 62 return pq.top(); // Kth largest element 63 } 64 65 // multiset 66 int findKthLargest4(vector<int>& nums, int k) { 67 multiset<int> mset; 68 69 for (int i = 0; i < nums.size(); ++ i) { 70 mset.insert(nums.at(i)); 71 72 if (mset.size() > k) 73 mset.erase(mset.begin()); // erase the element < Kth largest element 74 } 75 76 return *mset.begin(); // Kth largest element 77 } 78 }; 79 80 int main(int argc, char* argv[]) 81 { 82 Solution testSolution; 83 84 vector<vector<int>> aInputs = {{3,2,1,5,6,4}, {1,2,3,4,5}, {10,9,8,7,6}}; 85 vector<int> kInputs = {2, 4, 2}; 86 int result; 87 88 /* 89 5 90 2 91 9 92 */ 93 for (auto i = 0; i < aInputs.size(); ++ i) { 94 result = testSolution.findKthLargest(aInputs[i], kInputs[i]); 95 cout << result << endl; 96 result = testSolution.findKthLargest2(aInputs[i], kInputs[i]); 97 cout << result << endl; 98 result = testSolution.findKthLargest3(aInputs[i], kInputs[i]); 99 cout << result << endl; 100 result = testSolution.findKthLargest4(aInputs[i], kInputs[i]); 101 cout << result << endl; 102 } 103 104 return 0; 105 }
- Python同样可以使用sorted(),heapq.nlargest(),最大堆,K个元素的最小堆(类似优先队列),类似快排的分治。注意Python的heapq使用的是最小堆。实现最大堆比较tricky,把输入的nums转成-nums。
- 👏🏻 Python | 给你把这道题讲透 - 公瑾™ [215] - LeetCode Discuss
- Python different solutions with comments (bubble sort, selection sort, heap sort and quick sort). - LeetCode Discuss
- sort - Built-in Types — Python 3.7.4 documentation
- sorted - Built-in Functions — Python 3.7.4 documentation
- Sorting HOW TO — Python 3.7.4 documentation
- heapq — Heap queue algorithm — Python 3.7.4 documentation
1 class Solution: 2 # sorted() 3 def findKthLargest(self, nums: List[int], k: int) -> int: 4 return sorted(nums, reverse=True)[k - 1] 5 6 # heapq.nlargest() 7 def findKthLargest2(self, nums: List[int], k: int) -> int: 8 return heapq.nlargest(k, nums)[-1] 9 10 # Max Heap with heapq 11 def findKthLargest3(self, nums: List[int], k: int) -> int: 12 nums = [-num for num in nums] 13 14 heapq.heapify(nums) 15 16 for _ in range(k): 17 result = heapq.heappop(nums) 18 19 return -result 20 21 # Min Heap with heapq 22 def findKthLargest4(self, nums: List[int], k: int) -> int: 23 min_heap = [-float('inf')] * k 24 25 # min heap with k elements 26 heapq.heapify(min_heap) 27 28 for num in nums: 29 if num > min_heap[0]: 30 heapq.heappop(min_heap) 31 heapq.heappush(min_heap, num) 32 33 return min_heap[0] 34 35 # Divide and Conquer 36 def findKthLargest5(self, nums: List[int], k: int) -> int: 37 _left, _right = 0, len(nums) - 1 38 39 def partition(nums, left, right): 40 i, j, pivot = left, right, nums[left] 41 42 while i < j: 43 while i < j and nums[j] <= pivot: 44 j -= 1 45 if i < j: 46 nums[i] = nums[j] 47 i += 1 48 49 while i < j and nums[i] >= pivot: 50 i += 1 51 if i < j: 52 nums[j] = nums[i] 53 j -= 1 54 55 nums[i] = pivot 56 57 return i 58 59 while True: 60 pos = partition(nums, _left, _right) 61 62 if pos == k - 1: 63 return nums[k - 1] 64 elif pos < k - 1: 65 _left = pos + 1 66 else: 67 _right = pos - 1