*215. Kth Largest Element in an Array

1. 原始题目

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

 

2. 思路

可以利用优先队列存储元素,然后分别出对,每次出对都是最大元素,那么第k次出队时就是第k大元素了。然而此题本意并非在此。比较好的解法是利用快排中的partition操作!因为对于每次partition操作,都可以确定第m大的元素。如果是从小到大排列的数组,那么如果m>k,则应该在右子区间继续partition操作。如果m<k则应该在左子区间继续partition操作。如果m==k,则说明找到了,直接返回即可。

举例如下:

【42,46,67,3,34,7,66,21】将首元素进行partition后:【3,34,7,21,42,46,67,66】,此时m=4,如果找第k=4大的元素,那么正好找到了,直接返回即可。如找k=2的元素66,则应该继续在子区间【m+1:】来搜索,否则在【:m】区间搜索。

 

3. 解题

 1 def paitition(arr,left,right):         # pritition 快排核心思想:在v的左边元素都小于v,v右边元素都大于v
 2     if not arr: return None
 3     temp = arr
 4     arr = arr[left:right]
 5     
 6     v = arr[0]           # 取第一个元素作为pivot元素
 7     j = 0               # [l+1,j]>v  [j+1,i)>v
 8     for i in range(len(arr)):
 9         if arr[i]<v:      # 当前元素小于v则交换
10             arr[j+1],arr[i] = arr[i],arr[j+1]
11             j=j+1
12     arr[0],arr[j] = arr[j],arr[0]    # 最后将该首位元素pivot交换到合理位置
13     temp[left:right] = arr
14     return temp,left+j
15 
16 
17 class Solution:
18     def findKthLargest(self, nums, k):
19         if not nums:return None
20         left,right = 0,len(nums)
21         while True:
22             num, pos = paitition(nums,left,right)
23             if len(nums)-pos==k:
24                 return nums[pos]
25             elif len(nums)-pos>k:
26                 left = pos+1
27             else:
28                 right = pos+1

 

posted @ 2019-04-29 09:35  三年一梦  阅读(238)  评论(0编辑  收藏  举报