You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/** * initialize your data structure here. */varMedianFinder=function(){this.item=[];};/** * @param {number} num * @return {void} */MedianFinder.prototype.addNum=function(num){if(!this.item.length){this.item.push(num);}else{letstart=0;letend=this.item.length-1;letmid=Math.floor((start+end)/2);if(num<=this.item[start]){returnthis.item.unshift(num);}if(num>=this.item[end]){returnthis.item.push(num);}while(start<end){if(this.item[mid]===num){returnthis.item.splice(mid,0,num);}if(this.item[mid]>num){if(this.item[mid-1]<=num){returnthis.item.splice(mid,0,num);}else{end=mid-1;}}else{if(this.item[mid+1]>=num){returnthis.item.splice(mid+1,0,num);}else{start=mid+1;}}mid=Math.floor((end+start)/2);}this.item.splice(start,0,num);}};/** * @return {number} */MedianFinder.prototype.findMedian=function(){letmid=this.item.length/2;if(mid%1===0){// 偶数return(this.item[mid]+this.item[mid-1])/2;}else{// 奇数returnthis.item[mid-0.5];}};/** * Your MedianFinder object will be instantiated and called as such: * var obj = new MedianFinder() * obj.addNum(num) * var param_2 = obj.findMedian() */
Activity
sisterAn commentedon Jun 10, 2020
看到这个动态数组获取中位数问题,不要太激动,这太适合使用堆了,考察的就是堆的经典应用:中位数问题,详情可查看 前端进阶算法9:看完这篇,再也不怕堆排序、Top K、中位数问题面试了
堆的经典应用:
解法:利用堆
解题思路:
这里需要维护两个堆:
Math.floor(n/2) + 1个元素那么,根据题目要求,中位数就为:
当数组为动态数组时,每当数组中插入一个元素时,都需要如何调整堆喃?
如果插入元素比大顶堆的堆顶要大,则将该元素插入到小顶堆中;如果要小,则插入到大顶堆中。
当插入完成后,如果大顶堆、小顶堆中元素的个数不满足我们已上的要求,我们就需要不断的将大顶堆的堆顶元素或小顶堆的堆顶元素移动到另一个堆中,直到满足要求
代码实现:
其中小顶堆定义:
大顶堆定义:
复杂度分析:
addNum)的时间复杂度为 O(logn) ,每次插入完成后求中位数仅仅需要返回堆顶元素即可,findMedian时间复杂度为 O(1)如果数据流中所有整数都在 0 到 100 范围内,我们可以尝试使用计数排序,但计数排序的时间复杂度是O(n + m),其中 m 表示数据范围,复杂度较高,这里不适合,计数排序比较适合静态数组前k个最值问题 leetcode347:前 K 个高频元素
leetcode
Mitsuitou commentedon Jun 11, 2020