代码随想录算法训练营第十三天 | 239.滑动窗口最大值、347.前K个高频元素

68 阅读1分钟

239.滑动窗口最大值

347.前K个高频元素

239.滑动窗口最大值

  • 正解:在窗口滑动过程中,当队首元素是下一个弹出元素时shift,当加入的元素大于队尾元素时,一直弹出队尾元素直到新加入的元素满足单调条件
  • 注意点:pop和shift的区别;pop时使用的是while
var maxSlidingWindow = function(nums, k) {
    const q = [];
    const res = [];

    for (let i=0; i<k; i++) {
        while (q.length > 0 && nums[i] > q[q.length-1]) {
            q.pop();
        }
        q.push(nums[i]);
    }
    
    for (let j=0; j<nums.length-k+1; j++) {
        res.push(q[0]);
        if (q.length > 0 && q[0] === nums[j]) {
            q.shift();
        }
        while (q.length > 0 && nums[j+k] > q[q.length - 1]) {
            q.pop();
        }
        q.push(nums[j+k]);
    }

    return res;
};

347.前K个高频元素

  • 正解:小顶堆
var topKFrequent = function(nums, k) {
    if(nums.length === 1)   return nums;
    let map = new Map();
    for(let n of nums){
        if(!map.has(n)){
            map.set(n, 1);
        }else{
            map.set(n, map.get(n) + 1);
        }
    }

    let minHeapK = [];
    let i = 0;
    for(let m of map){
        if(i<k) minHeapK.push(m[0]);
        if(i===k)   buildMinHeap(minHeapK, k, map);
        if(i>=k){
            if(m[1] > map.get(minHeapK[0])){
                minHeapK[0] = m[0];
                heapify(minHeapK, 0, k, map);
            }
        }
        i++;
    }
    return minHeapK;
};

let buildMinHeap = function(num, size, map){
    for(let i=Math.floor(size/2-1); i>=0; i--){
        heapify(num, i, size, map);
    }
}

let heapify = function(num, cur, size, map){
    let lson = 2*cur+1, rson = 2*cur+2;
    let min = cur;
    if(lson<size && map.get(num[lson]) < map.get(num[min]))   min = lson;
    if(rson<size && map.get(num[rson]) < map.get(num[min]))   min = rson;
    if(min !== cur){
        [num[cur], num[min]] = [num[min], num[cur]];
        heapify(num, min, size, map);
    }
}