215. Kth Largest Element in an Array

首先复习一下quicksort.

先理解partition函数,就是选序列的最后一个数作为pivot,比它小的排到它左边,比它大的在它右边,它在中间。但是它左右的部分并没有排序。

返回值是这个pivot所在的位置,pivot所在位置就是它最终的位置,也就是说比如index是5,说明它就是第6大的数。

quicksort里面就是调用partition,不断对其左右进行排序,直到low >= high

partition伪代码

 1 paritition(arr, low, hight):
 2 
 3   index = low;//index是第一个不小于pivot的数的index
 4 
 5   对于从low到high的数:
 6 
 7     如果这个数比pivot小,那么:
 8       把index和这个数交换
 9       index++
10   swap pivot和index所在的数
11 
12 返回index

 

 

quicksort伪代码

1 quicksort(arr, low, high):
2 
3   如果low<high:
4 
5     partitionIndex = partition(arr, low, high);
6     partition(arr, low, partitionIndex - 1);
7     partition(arr, partitionIndex + 1, high);

 

 

所以这道题的思路就是,先partition一次,然后如果正好是第k-1个,那就返回,不然如果partition完左侧加起来的数字数目已经超过了k-1,那么说明右侧反正都小于这个pivot了,就只对左侧递归,不然就对右侧递归

 1    public int findKthLargest(int[] nums, int k) {
 2         if (nums.length == 1) {
 3           return nums[0];
 4         }
 5         int idx = -1;
 6         int left = 0, right = nums.length - 1;
 7         while (idx != k - 1) {
 8           idx = partition(nums, left, right);
 9           if(idx > k - 1) {
10                right = idx - 1;
11           } else {
12               left = idx + 1;
13           }
14         }
15         return nums[idx];
16    }
17     
18     private int partition(int[] nums, int low, int high) {
19         int index = low;
20         int pivot = nums[high];
21         for(int i = low; i < high; i++) {
22             if(nums[i] > pivot) {
23                 swap(nums, index, i);
24                 index++;
25             }
26         }
27         swap(nums, index, high);
28         return index;
29     }
30     
31     private void swap(int[] nums, int idx1, int idx2) {
32         int tmp = nums[idx1];
33         nums[idx1] = nums[idx2];
34         nums[idx2] = tmp;
35     }

 

另外一种方法是用PriorityQueue。

PQ的值得记录的:

1.自动维护从小到大的顺序,可以poll(),peek().但是不方便得到某一位置上的元素。

2.当然可以自己写comparator,但是如果单纯想逆序的话,可以new PQ<>(Collections.reverseOrder())

 1     public int findKthLargest(int[] nums, int k) {
 2         PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
 3         for(int i = 0; i < nums.length; i++) {
 4             pq.offer(nums[i]);
 5             if(pq.size() > k) {
 6                 pq.poll();
 7             }
 8         }
 9         return pq.poll();
10     }

 

posted @ 2016-07-24 03:08  warmland  阅读(190)  评论(0编辑  收藏  举报