代码改变世界

Kth Largest Element in an Array

2017-03-02 13:37  老左的博客  阅读(161)  评论(0编辑  收藏  举报

题目描述:

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.

题目大意:

在未排序的数组中找出第k大的元素。(k一定是有效的, 1 ≤ k ≤ 数组长度)

注意是排序之后的第k大元素,不是第k个不重复的元素

示例:

给定数组[3,2,1,5,6,4],k = 2,return 5.

解题思路:

(1)堆排序(O(nlogn)),使用数组的前k个元素创建一个最小堆min_heap,剩下的的n-k个元素依次插入堆,并弹出最小值,保持堆大小为k,最后取min_heap[0]即为第k大的元素。

 1 class Solution(object):
 2     def findKthLargest(self, nums, k):
 3         """
 4         :type nums: List[int]
 5         :type k: int
 6         :rtype: int
 7         """
 8         from heapq import heappush, heappushpop
 9         heap = []
10         for i in xrange(k):
11             heappush(heap, nums[i])
12             
13         for i in xrange(k, len(nums)):
14             heappushpop(heap, nums[i])
15             
16         return heap[0]

(2)快速选择排序(O(n)),参考 http://www.cs.yale.edu/homes/aspnes/pinewiki/QuickSelect.html

 1 from random import choice
 2 
 3 class Solution(object):
 4     def findKthLargest(self, nums, k):
 5         """
 6         :type nums: List[int]
 7         :type k: int
 8         :rtype: int
 9         """
10         # 随机选取一个数字
11         pivot = choice(nums)
12         # 比pivot分别大的小的放到不同的a1,a2
13         a1, a2 = [], []
14         for i in nums:
15             if i > pivot:
16                 a1.append(i)
17             elif i < pivot:
18                 a2.append(i)
19         
20         # a1的长度大于k,递归a1      
21         if k <= len(a1):
22             return self.findKthLargest(a1, k)
23         # a2的长度大于len(nums) - k,说明第k大元素为a2的第k-(len(nums)-len(a2))大元素
24         elif k > len(nums) - len(a2):
25             return self.findKthLargest(a2, k - (len(nums) - len(a2)))
26         
27         # k = len(nums) - len(a2), pivot为第k大的元素
28         return pivot