(重点复习)[LeetCode]Kth Largest Element in an Array

Question

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.


本题难度Easy。有3种算法分别是: 排序、优先队列和快速排序

题意

题目说的是要第K大的元素,而不是第K大的数。

1、排序法

复杂度

时间 O(NlogN) 空间 O(1)

思路

排序后,倒数第K个就是答案。

代码

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        return nums[nums.length-k];
    }
}

2、优先队列

复杂度

时间 O(NlogK) 空间 O(K)

思路

遍历数组时将数字加入优先队列(堆),一旦堆的大小大于k就将堆顶元素去除,确保堆的大小为k。遍历完后堆顶就是返回值。

优先队列就是最小堆,最小值在根节点。

代码

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> p = new PriorityQueue<Integer>();
        for(int i = 0 ; i < nums.length; i++){
            p.add(nums[i]);
            if(p.size()>k) p.poll();
        }
        return p.poll();
    }
}

3、快速排序

复杂度

时间 Avg O(N) Worst O(N^2) 空间 O(1)

思路

跟快速排序一个思路。先取一个枢纽值,将数组中小于枢纽值的放在左边,大于枢纽值的放在右边,最后把枢纽值放到分界点(具体请看被忽视的 partition 算法)。如果分界点后面有k-1个数,说明分界点的数就是第k个数;否则,如果分界点后的数大于k-1,则在右半边做同样的搜索;如果分界点后的数小于k-1,则在左半边做同样的搜索。

背景资料:被忽视的 partition 算法
实现快速排序的方法很多,最直观的就是用两个List,一个存放小于pivot,一个存放大于pivot,但是这样既低效又浪费空间,所以推荐使用partition算法。它的核心实际上就是双指针法:

这里写图片描述

begin代表的是小于等于pivot值的边界(不含begin本身),end代表的是大于等于pivot的边界(不含end本身),这样两指针逐渐往中间靠拢,最后begin==end其位置就是pivot所在点。

注意

  1. 第3行是return quickSort(0,nums.length,nums,k);
    而不是return quickSort(0,nums.length-1,nums,k);
  2. 第19行是return quickSort(begin+1,r,arr,k);
    而不是return quickSort(begin,r,arr,k);

代码

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSort(0,nums.length,nums,k);
    }
    private int quickSort(int l,int r,int[] arr, int k){
        int pivot = arr[l],begin=l,end=r;
        while(begin < end)
        {
            while(begin < end && arr[--end] >= pivot);
            arr[begin] = arr[end];
            while(begin < end && arr[++begin] <= pivot);
            arr[end] = arr[begin];
        }
        int mid=begin;
        arr[mid] = pivot;
        if(arr.length-mid<k)
            return quickSort(l,mid,arr,k);
        else if(arr.length-mid>k)
            return quickSort(mid+1,r,arr,k);
        else 
            return pivot;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值