215. Kth Largest Element in an Array

一、题目

  1、审题

  

  2、分析

    在一个无序的整形数组中找出第 K 大的元素。

 

二、解答

  1、思路:

    方法一、

      排序后直接返回。

1     public int findKthLargest1(int[] nums, int k) {
2         int len = nums.length;
3         Arrays.sort(nums);
4         return nums[len - k];
5     }

 

    方法二、采用 PriorityQueue

      PriorityQueue 对进入的元素进行排序,每次出队的都是最小的元素;

 1     public int findKthLargest2(int[] nums, int k) {
 2         // 优先队列
 3         PriorityQueue<Integer> pq = new PriorityQueue<>();
 4         for(int val: nums) {
 5             pq.offer(val);
 6             if(pq.size() > k)
 7                 pq.poll();
 8         }
 9         return pq.peek();
10     }

 

    方法三、

      1、对数组采用快速排序,确定第一个元素在有序时的下标 j

      2、若 j == k 则返回此元素

        若 j > k 则 high = j - 1; 在对数组左半部分进行快速排序;

        若 j < k,则 low =  j + 1; 在对数组右半部分进行快速排序;

        直到 j == k, 返回此元素即可

 1     public int findKthLargest3(int[] nums, int k) {
 2         
 3         k = nums.length - k;
 4         int low = 0, high = nums.length - 1;
 5         while(low < high) {
 6             int j = partition(nums, low, high);
 7             if(j < k)
 8                 low = j + 1;
 9             else if(j > k)
10                 high = j - 1;
11             else 
12                 break;
13         }
14         return nums[k];
15     }
16     
17     //. 快速排序
18     private int partition(int[] nums, int low, int high) {
19         int i = low, j = high + 1;
20         while(true) {
21             while(i < high && nums[++i] < nums[low]);
22             while(j > low && nums[low] < nums[--j]);
23             if(i >= j)
24                 break;
25             exchange(nums, i, j);
26         }
27         exchange(nums, low, j);
28         return j;
29     }
30 
31     private void exchange(int[] nums, int i, int j) {
32         int tmp = nums[i];
33         nums[i] = nums[j];
34         nums[j] = tmp;
35     }

  

  对方法三进行优化:

    为了防止输入的是有序的元素,所造成的效率最差的情况,可以先对数组元素进行乱序。

 1     public int findKthLargest(int[] nums, int k) {
 2         shuffle(nums);
 3         k = nums.length - k;
 4         int low = 0;
 5         int high = nums.length - 1;
 6         while(low < high) {
 7             int j = partition(nums, low, high);
 8             if(j < k) 
 9                 low = j + 1;
10             else if(j > k)
11                 high = j - 1;
12             else
13                 break;
14         }
15         return nums[k];
16     }
17     
18     // we can randomize the input, so that even when the worst case input would be provided the algorithm wouldn't be affected. 
19     // So all what it is needed to be done is to shuffle the input.
20     private void shuffle(int[] nums) {
21         Random random = new Random();
22         for (int i = 1; i < nums.length; i++) {
23             int r = random.nextInt(i + 1);
24             exchange(nums, i, r);
25         }
26     }
27     
28     //. 快速排序
29     private int partition(int[] nums, int low, int high) {
30         int i = low, j = high + 1;
31         while(true) {
32             while(i < high && nums[++i] < nums[low]);
33             while(j > low && nums[low] < nums[--j]);
34             if(i >= j)
35                 break;
36             exchange(nums, i, j);
37         }
38         exchange(nums, low, j);
39         return j;
40     }
41 
42     private void exchange(int[] nums, int i, int j) {
43         int tmp = nums[i];
44         nums[i] = nums[j];
45         nums[j] = tmp;
46     }

 

posted @ 2018-11-01 22:06  skillking2  阅读(120)  评论(0编辑  收藏  举报