东莞网站建设-搜盟网,公司活动策划方案怎么做,网站开发提供的服务,石家庄刚刚发生的事数据流中的第 K 大元素
问题描述
设计一个找到数据流中第 k 大元素的类#xff08;class#xff09;。注意#xff0c;这是指在已排序的顺序中处于第 k 个位置的元素#xff0c;而不是第 k 个不同的元素。
请实现 KthLargest 类#xff1a;
KthLargest(int k, int[] nums)…数据流中的第 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 (数据流: [2,3,4,5,8]) kthLargest.add(5); // return 5 (数据流: [2,3,4,5,5,8]) kthLargest.add(10); // return 5 (数据流: [2,3,4,5,5,8,10]) kthLargest.add(9); // return 8 (数据流: [2,3,4,5,5,8,9,10]) kthLargest.add(4); // return 8 (数据流: [2,3,4,4,5,5,8,9,10])算法思路最小堆核心思想维护一个大小为k的最小堆堆顶元素就是第k大的元素堆中始终保存数据流中最大的k个元素当堆大小超过k时移除堆顶最小的元素为什么使用最小堆最小堆的堆顶是堆中最小的元素如果堆中有k个元素堆顶就是第k大的元素当有新元素加入时如果新元素比堆顶大它会替换掉堆顶保持堆中始终是最大的k个元素代码实现方法一最小堆importjava.util.PriorityQueue;classKthLargest{privateintk;privatePriorityQueueIntegerminHeap;/** * 初始化KthLargest对象 * * param k 第k大的元素 * param nums 初始数据流 */publicKthLargest(intk,int[]nums){this.kk;// 创建最小堆PriorityQueue默认是最小堆this.minHeapnewPriorityQueue();// 将初始数组中的元素逐个加入堆for(intnum:nums){add(num);}}/** * 添加元素到数据流并返回第k大元素 * * param val 要添加的元素 * return 当前数据流中第k大的元素 */publicintadd(intval){// 将新元素加入堆minHeap.offer(val);// 如果堆大小超过k移除堆顶最小元素if(minHeap.size()k){minHeap.poll();}// 堆顶就是第k大的元素returnminHeap.peek();}}算法分析时间复杂度初始化O(N log k)其中N是初始数组长度add操作O(log k)堆操作的时间复杂度空间复杂度O(k)堆中最多存储k个元素算法过程k3, nums[4,5,8,2]初始化添加4堆[4]大小1≤3添加5堆[4,5]大小2≤3添加8堆[4,5,8]大小3≤3添加2堆[4,5,8,2] → 大小3 → 移除2 → 堆[4,5,8]堆状态[4,5,8]最小堆堆顶4add操作add(3)堆[4,5,8,3] → 大小3 → 移除3 → 堆[4,5,8]返回堆顶4add(5)堆[4,5,8,5] → 大小3 → 移除4 → 堆[5,5,8]返回堆顶5add(10)堆[5,5,8,10] → 大小3 → 移除5 → 堆[5,8,10]返回堆顶5add(9)堆[5,8,10,9] → 大小3 → 移除5 → 堆[8,9,10]返回堆顶8add(4)堆[8,9,10,4] → 大小3 → 移除4 → 堆[8,9,10]返回堆顶8最终数据流[2,3,4,4,5,5,8,9,10]最大的3个元素[8,9,10]第3大元素8测试用例publicclassTestKthLargest{publicstaticvoidmain(String[]args){// 测试用例1标准示例KthLargestkthLargest1newKthLargest(3,newint[]{4,5,8,2});System.out.println(Test 1:);System.out.println(add(3): kthLargest1.add(3));// 4System.out.println(add(5): kthLargest1.add(5));// 5System.out.println(add(10): kthLargest1.add(10));// 5System.out.println(add(9): kthLargest1.add(9));// 8System.out.println(add(4): kthLargest1.add(4));// 8System.out.println();// 测试用例2k1找最大值KthLargestkthLargest2newKthLargest(1,newint[]{});System.out.println(Test 2 (k1):);System.out.println(add(1): kthLargest2.add(1));// 1System.out.println(add(3): kthLargest2.add(3));// 3System.out.println(add(2): kthLargest2.add(2));// 3System.out.println(add(4): kthLargest2.add(4));// 4System.out.println();// 测试用例3k等于数组长度KthLargestkthLargest3newKthLargest(2,newint[]{0});System.out.println(Test 3 (k2):);System.out.println(add(-1): kthLargest3.add(-1));// -1System.out.println(add(1): kthLargest3.add(1));// 0System.out.println(add(-2): kthLargest3.add(-2));// -1System.out.println(add(-4): kthLargest3.add(-4));// -1System.out.println(add(3): kthLargest3.add(3));// 0System.out.println();// 测试用例4大量重复元素KthLargestkthLargest4newKthLargest(3,newint[]{5,5,5});System.out.println(Test 4:);System.out.println(add(5): kthLargest4.add(5));// 5System.out.println(add(5): kthLargest4.add(5));// 5System.out.println(add(10): kthLargest4.add(10));// 5System.out.println();// 测试用例5负数KthLargestkthLargest5newKthLargest(2,newint[]{-1,-2,-3});System.out.println(Test 5:);System.out.println(add(-4): kthLargest5.add(-4));// -2System.out.println(add(0): kthLargest5.add(0));// -1System.out.println(add(1): kthLargest5.add(1));// 0System.out.println();// 测试用例6空初始数组KthLargestkthLargest6newKthLargest(2,newint[]{});System.out.println(Test 6:);System.out.println(add(1): kthLargest6.add(1));// 1 (堆大小2)System.out.println(add(2): kthLargest6.add(2));// 1 (堆[1,2])System.out.println(add(3): kthLargest6.add(3));// 2 (堆[2,3])System.out.println(add(0): kthLargest6.add(0));// 2 (堆[2,3])}}关键点堆的大小始终维护堆大小为k超过k时移除最小元素堆顶确保堆中始终是最大的k个元素为什么是最小堆而不是最大堆最小堆能快速获取k个最大元素中的最小值即第k大最大堆需要存储所有元素空间复杂度为O(N)边界情况处理初始数组为空k1找最大值k大于初始数组长度重复元素常见问题为什么不用最大堆最大堆需要存储所有元素才能找到第k大空间复杂度O(N)最小堆只需存储k个元素空间效率更高时间复杂度O(log k)堆的插入和删除操作时间复杂度都是O(log size)堆的大小始终≤k所以是O(log k)找第k小元素使用最大堆维护最小的k个元素堆顶就是第k小的元素