一、滑动窗口最大值
问题要点
通过长度为窗口大小的单调递减队列,保证队尾为队列的最大值
push的思路:如果入队的元素大于队首的元素,则不断出队,知道遇到大于当前元素
pop的思路:如果窗口要移除的元素等于单调队列的队尾元素,则队列弹出元素,否则队列不操作
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
let queue = []
let result = []
for(let i = 0; i < nums.length; i++) {
if(i >= k && nums[i-k] === queue[0]) {
queue.shift()
}
while(queue.length && queue[queue.length - 1] < nums[i]) {
queue.pop()
}
queue.push(nums[i])
if(i >= k - 1) {
result.push(queue[0])
}
}
return result
};
二、前K个高频元素
问题要点
先要构造大小为k的小顶堆,然后把剩余的元素从k位置开始,跟堆顶元素比较,如果比堆顶大,则移除堆顶,把该元素放到堆顶,进行headAdjust,调整为小顶堆,最终剩下来的小顶堆就是top k的元素
class HeapQueue {
queue = []
map = null
constructor(queue, map) {
this.queue = queue
this.map = map
}
heapify(k) {
for (let i = Math.floor((k - 1) / 2); i >= 0; i--) {
this.heapAdjust(i, k - 1)
}
}
heapAdjust(index, end) {
let left = 2 * index + 1
let right = left + 1
while (left <= end) {
let target = index;
if (this.map.get(this.queue[left]) < this.map.get(this.queue[target])) {
target = left
}
if (right <= end && this.map.get(this.queue[right]) < this.map.get(this.queue[target])) {
target = right
}
if (target === index) {
break
}
[this.queue[target], this.queue[index]] = [this.queue[index], this.queue[target]];
index = target
left = 2 * index + 1
right = left + 1
}
}
heappop() {
let size = this.queue.length
[this.queue[0], this.queue[size - 1]] = [this.queue[size - 1], this.queue[0]];
let top = this.queue.pop()
this.heapAdjust(0, size - 2)
return top
}
heappush(val) {
this.queue.push(val)
let size = this.queue.length
let i = size - 1
while (Math.floor((i - 1) / 2) >= 0) {
let curRoot = Math.floor((i - 1) / 2)
if (this.map.get(this.queue[curRoot]) < this.map.get(this.queue[i])) {
break
}
nums[i] = nums[curRoot]
i = curRoot
}
}
}
function topKFrequent(nums, k) {
let map = new Map
for (const item of nums) {
map.set(item, (map.get(item) || 0) + 1)
}
let arr = [...new Set(nums)]
let heapQueue = new HeapQueue(arr, map)
heapQueue.heapify(k)
for (let i = k; i < heapQueue.queue.length; i++) {
if (map.get(heapQueue.queue[i]) > map.get(heapQueue.queue[0])) {
[heapQueue.queue[i], heapQueue.queue[0]] = [heapQueue.queue[0], heapQueue.queue[i]];
heapQueue.heapAdjust(0, k - 1)
}
}
return heapQueue.queue.slice(0, k)
}