vector删除第i个元素_LeetCode每日一题 Q215数组中的第K个最大元素

Question 215: Kth Largest Element in an Array 
Difficulty: Medium

题目描述

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

示例:

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

说明:

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

题目分析

显然这道题可以先排序,再去找第K大的值,但这种暴力解法显然不是最优解。在这里我们可以维护一个大小为K最小堆minheap来实现。

本题目的算法并不难,但我们需要了解一下的概念。

关于堆

堆就是用数组实现的二叉树,所有它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。

堆的常用方法:

•构建优先队列•支持堆排序•快速找出一个集合中的最小值(或者最大值)

堆分为两种:最大堆 和 最小堆,两者的差别在于节点的排序方式。

在最大堆中,父节点的值比每一个子节点的值都要大。在最小堆中,父节点的值比每一个子节点的值都要小。这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立。

8868ba13d469270f71143d640eb84243.png

这是一个最大堆,,因为每一个父节点的值都比其子节点要大。10 比 7 和 2 都大。7 比 5 和 1都大。

根据这一属性,那么最大堆总是将其中的最大值存放在树的根节点。而对于最小堆,根节点中的元素总是树中的最小值。堆属性非常的有用,因为堆常常被当做优先队列使用,因为可以快速的访问到“最重要”的元素。

题解

显然,遍历数组中的元素,并维护一个大小为K的minHeap,最后堆顶元素即为所求。遍历每个元素,并每次都要进行一次heapify,则时间复杂度为O(N log K),由于维护了大小为K的minHeap则空间复杂度为O(log K)

e47f072ff68e708a24bdf463af91f4a1.gif

//Java 解法class Solution {    public int findKthLargest(int[] nums, int k) {        PriorityQueue<Integer> minHeap = new PriorityQueue<>(k,        new Comparator<Integer>(){            @Override            public int compare(Integer o1, Integer o2){                if(o1.equals(o2)) return 0;                return o1 < o2 ? -1 : 1;            }        }                                                            );        for(int i = 0; i < nums.length; i++){            if(minHeap.size() < k){                minHeap.add(nums[i]);            }else if(nums[i] > minHeap.peek()){                minHeap.poll();                minHeap.add(nums[i]);            }        }        return minHeap.poll();    }}
#python 解法class Solution:    def findKthLargest(self, nums, k):        """        :type nums: List[int]        :type k: int        :rtype: int        """        return heapq.nlargest(k, nums)[-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值