查找数据流中的第K大元素
地址:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/,题号:703。
【解题思路】
这道题的思路是保存前K个最大值,每进来一个元素,判断这个元素跟堆顶元素(最小值)比较,如果大于最小值,就把堆顶值踢出,插入新值,然后维持整个堆的顺序。
- 方法一:sorted 排序维持。对这K个值的堆进行sorted排序;
- 方法二:最小堆维持。维持过程如下图。

二叉堆的写法比较麻烦,这里就不做展示,可以自行去LeetCode查看示例。
var KthLargest = function(k, nums) {this.k = k;this.minHeap = []; // 维持K个最大值的最小堆var that = this;nums.forEach((item)=> {this.add(item);})};KthLargest.prototype.add = function(val) {let length = this.minHeap.length;if(length < this.k){ // 最小堆的长度是否已经超出K个值,没有直接插入this.offer(val);} else if(this.peek()<val) { // 判断堆顶元素是否小于插入值,如果是,把堆顶元素踢出,插入新元素this.minHeap.shift();this.offer(val);}return this.peek();};/*** 维持整个堆的顺序:①sorted②维持最小堆*/KthLargest.prototype.offer = function(val) {// 直接保存,然后sorted维持this.priorityQueue.push(val);this.priorityQueue.sort((a,b)=>a-b);//splice维持let pos=0;let length = this.minHeap.length;for(let i=0;i<=length;i++) {if(this.minHeap[i]>=val) {pos = i;break;} else {pos = i;}}this.minHeap.splice(pos, 0, val);}KthLargest.prototype.peek = function() {return this.minHeap[0];}
那么,它们的时间复杂度是多少呢?
对于sorted排序方式,假设有n个元素进来,那么就是n次循环,然后对k个数进行排序,假设使用最佳的排序方式是快排,时间复杂度就是 O(N· klogK);
对于二叉堆方式,同样是n个元素进来,那么就是n次循环,最优的情况是比堆顶元素少,那就是O(N·1),最差的情况是对二叉堆进行调整,调整的时间复杂度是 O(N·logk),那么取最差的情况logk,对比sorted排序还是有优势。
to be continue…
