leetcode----215. Kth Largest Element in an Array

链接:

https://leetcode.com/problems/kth-largest-element-in-an-array/

大意:

给定一个无序且有重复数字的整型数组nums,要求找出第k大的数(k为有效数字,1 <= k <= nums.length)。例子:

思路:

基于堆的思想。维护一个大小始终为k的小根堆,当当前元素num大于堆顶元素时,将堆顶元素出堆,并将当前元素加入堆中(同时调整堆)。

可以使用Java中自带的以堆思想实现的数据结构优先级队列(PriorityQueue)来解决 (不用重复造轮子了。。)

代码:

class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();//小根堆
        for (int num : nums) {
            if (pq.size() < k)
                pq.offer(num);
            else {
                int val = pq.peek(); // 获得堆顶元素
                if (num > val) {
                    pq.poll();
                    pq.offer(num);
                }
            }
        }
        return pq.peek();
    }
}

结果:

结论:

除了可以使用堆排序思想来解决,另一个高效方法是通过快排思想但并不对所有元素进行排序,只为找到第k个位置上的数。

改进:(自己写了个类似快排,效率高的原因得归功于基准的随机选取!!!)

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return myQuickSort(nums, k, 0, nums.length - 1);
    }
    public int myQuickSort(int[] nums, int k, int s, int e) {
        // 随机选择基准
        Random r = new Random();
        int index = r.nextInt(e - s + 1) + s; // 随机选择基准后,效率大大提高
        swap(nums, index, s); // 将首元素与基准交换
        int axes = nums[s]; // 基准
        int start = s + 1, end = e;
        // 比axes大或等于的元素在axes的左边 比axes小的元素在axes右边
        while (start <= end) {
            // 找到第一个比axes小的元素
            while (start <= end && nums[start] >= axes) {
                start++;
            }
            // 找到第一个比axes大或等于的元素 
            while (end >= start && nums[end] < axes) {
                end--;
            }
            // axes为数组的第end+1大元素 end为axes在nums中的位置
            if (start > end) {
                if (end + 1 == k)
                    return axes;
                swap(nums, s, end);
                if (end + 1 > k) 
                    return myQuickSort(nums, k, s, end - 1);
                if (end + 1 < k)
                    return myQuickSort(nums, k, end + 1, e);
            }
            swap(nums, start++, end--);
        }
        if (end + 1 == k)
            return axes;
        swap(nums, s, end);
        if (end + 1 > k) 
            return myQuickSort(nums, k, s, end - 1);
        else 
            return myQuickSort(nums, k, end + 1, e);
    }
    public void swap(int[] nums, int idx1, int idx2) {
        int tmp = nums[idx1];
        nums[idx1] = nums[idx2];
        nums[idx2] = tmp;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值