手撸二叉树之数据流中的第 K 大元素

举报
HelloWorld杰少 发表于 2022/09/19 13:05:27 2022/09/19
【摘要】 Hello, 大家好,今天给大家带来的关于二叉树相关的算法题是数据流中的第 K 大元素,正文如下: 题目设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。请实现 KthLargest 类:KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。int add(int val) 将 v...

Hello, 大家好,今天给大家带来的关于二叉树相关的算法题是数据流中的第 K 大元素,正文如下:

题目

设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。

请实现 KthLargest 类:

  • KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
  • int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。

示例

输入:
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
输出:
[null, 4, 5, 5, 8, 8]

解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3);   // return 4
kthLargest.add(5);   // return 5
kthLargest.add(10);  // return 5
kthLargest.add(9);   // return 8
kthLargest.add(4);   // return 8

解题思路

TopK 算法在面试中常问, 本题的解题思路如下:

  1. 使用大小为 k 的小根堆,在初始化的时候,保证堆中的元素个数不超过 K。
  2. 在每次 add() 的时候,将新元素 push() 到堆中,如果此时堆中的元素超过了 K,那么需要把堆中的最小元素(堆顶)pop()出来。
  3. 此时堆中的最小元素(堆顶)就是整个数据流中的第 K 大元素。

在本题中,我使用的是优先队列来存储前 K 大的元素,其中优先队列的队头为队列中最小的元素,也就是第 kk 大的元素。

代码实现

class KthLargest {
    // 永远只记录 k 个值
    PriorityQueue<Integer> pq;
    int k;
    public KthLargest(int k, int[] nums) {
        this.k = k;
        pq = new PriorityQueue<Integer>();
        for (int i = 0; i < nums.length; i++) {
            add(nums[i]);
        }
    }
    
    public int add(int val) {
        pq.offer(val);
        // 如果队列的长度超过 K,则弹出
        if(pq.size() > k){
            pq.poll();
        }
        // 返回第k大的值
        return pq.peek();
    }
}

最后

复杂度分析

  • 时间复杂度:初始化时间复杂度为:O(nlogk) ,其中 n 为初始化时 nums 的长度;单次插入时间复杂度为:O(logk);

  • 空间复杂度:O(k)。需要使用优先队列存储前 k 大的元素。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。