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/
  • 第二种解法,用快排中的分治方法。因为快排中每一趟排序之后能找出第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
  • 第三种解法可以用STL priority_queue。因为优先队列实际上用到了最大堆,默认情况下top返回最大元素,K次循环就可以找到第K大的元素。
    • priority_queue - C++ Reference
      • http://www.cplusplus.com/reference/queue/priority_queue/
  • 第四种解法可以用STL multiset。多元集合默认情况下按升序排列,所以维护一个K个元素的集合,begin()就是第K大的元素。
    • multiset - C++ Reference
      • http://www.cplusplus.com/reference/set/multiset/
  • 第五种解法可以用堆排序。
    • 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
  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 }
View Code

 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
View Python Code

 

posted on 2018-02-16 18:11  浩然119  阅读(315)  评论(0编辑  收藏  举报