美文网首页
剑指offer 59-1 滑动窗口内的最大值

剑指offer 59-1 滑动窗口内的最大值

作者: 再凌 | 来源:发表于2020-05-08 11:06 被阅读0次

    给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

    使用一个队列记录滑动窗口内的最大值.

    队列的规则如下:

    • 队列是严格降序排列
    • 新来的元素从队尾依次向前比较, 直到找到自己的位置后, 将后面的元素都删除
    • 如果滑动窗口丢失的元素是队首元素, 那么队列弹出队首元素

    通过这样的方式, 保证了最大值队列始终不为空, 同时最大值一定是队首元素

    或许有人会问, 规则(2) 中最坏情况是每次的插入元素是升序, 导致时间复杂度N2? 不然, 如果是升序排列, 那么每次新增的元素都会将queue.size()变为1, 那么时间复杂度就降为了常数量

    /**
     * Note: The returned array must be malloced, assume caller calls free().
     */
    int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize){
        *returnSize = 0;
        if(!nums || numsSize ==0) return NULL;
        if(k == 0) return  NULL;
    
        *returnSize = numsSize - k + 1;
        int *ret = malloc(sizeof(int) * (*returnSize));
        int reti = 0;
    
        //一个队列, 记录窗口内的最大值, 如果新来的比队列所有的都大, 就清空队列; 否则放入
        int* maxqueue = malloc(sizeof(int) * k);
        int qhead = 0, qi = qhead;
    
        //第一次
        maxqueue[qi%k] = nums[0];
        int i = 1;
        while(i < k)
        {
            if(nums[i] > maxqueue[qhead%k])
            {
                maxqueue[qhead%k] = nums[i];
                qi = qhead;
                i++;
                continue;
            }
            //从队尾向前找适合自己的位置,并把之后的都删掉
            while(nums[i] > maxqueue[qi%k])
            {
                qi--;
            }
            qi++;
            maxqueue[qi%k] = nums[i];
            i++;
        }
        ret[reti++] = maxqueue[qhead%k];
        for(i = k; i < numsSize ; i++)
        {
            //最大的出队了
            if(nums[i - k] == maxqueue[qhead%k])
            {
                qhead++;
            }
    
            //如果新增来的最大
            if(nums[i] > maxqueue[qhead%k])
            {
                maxqueue[qhead%k] = nums[i];
                qi = qhead;
            }
            //新来的元素从队尾开始找自己的位置, 并把之后的都删掉
            else
            {
                while(nums[i] > maxqueue[qi%k])
                {
                    qi--;
                }
                qi++;
                maxqueue[qi%k] = nums[i];
            } 
            
             ret[reti++] = maxqueue[qhead%k];   
            
        }
        return ret;
    }
    

    时间复杂度: N
    空间复杂度: K

    相关文章

      网友评论

          本文标题:剑指offer 59-1 滑动窗口内的最大值

          本文链接:https://www.haomeiwen.com/subject/ffnxnhtx.html