打卡 DAY 35 滑动窗口最大值

力扣原题链接

一、题目描述

二、思路

遍历滑动窗口内整数数组,按顺序创造一个单调递减队列(不需要对整数数组进行排序,直接按原数组顺序遍历下去就行),当遍历到的元素小于等于队列中入口元素,则将该元素放入队列;当遍历到的元素大于队列中入口元素,弹出入口元素直至入口元素大于等于该元素:

当滑动窗口移动时,若要移除的元素的值等于出口元素的值,则弹出出口元素,若不等则不作操作;若要进入窗口的元素的值小于等于入口元素,则直接放入队列,若大于入口元素,则弹出入口元素直至入口元素大于等于该元素:

三、解题过程

  • 实现元素放入队列接口函数

  • 若要进入窗口的元素的值小于等于入口元素,则直接放入队列,若大于入口元素,则弹出入口元素直至入口元素大于等于该元素:
void push(int* queue, int* arr,int* back, int* front, int index){//arr是整数数组
    if(index == 0 || arr[index] <= queue[(*back) - 1]){
        queue[(*back)++] = arr[index];
        return;
    }
    while(*back > *front && arr[index] > queue[(*back) - 1]){
        (*back)--;
    }
    queue[(*back)++] = arr[index];
}
  • 实现弹出队列元素接口函数

  • 若要移除的元素的值等于出口元素的值,则弹出出口元素,若不等则不作操作:
void pop(int* queue, int* arr, int* front, int index){
    if(arr[index] != queue[*front]) return;
    (*front)++;
}
  • 初始化结果数组的长度

    *returnSize = numsSize - k + 1;
  • 初始化队列及入口、出口元素下标

    int front = 0;
    int back = 0;
    int* queue = (int*)malloc(sizeof(int) * numsSize);
  • 将数组前k个元素放入队列并得到结果数组的第一个元素

    int i = 0;
    while(i < k){
        push(queue, nums, &back, &front, i);
        i++;
    }
    int* res = (int*)malloc(sizeof(int) * (*returnSize));
    int j = 0;
    res[j++] = queue[front];
  • 移动滑动窗口

    //窗口最后一个元素下标为i,将要移除的元素下标为i - k
    while(i < numsSize){
        pop(queue, nums, &front, i - k);
        push(queue, nums, &back, &front, i);
        res[j++] = queue[front];
        i++;
    }
  • 返回结果数组

    return res;

四、代码

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
void push(int* queue, int* arr,int* back, int* front, int index){//arr是整数数组
    if(index == 0 || arr[index] <= queue[(*back) - 1]){
        queue[(*back)++] = arr[index];
        return;
    }
    while(*back > *front && arr[index] > queue[(*back) - 1]){
        (*back)--;
    }
    queue[(*back)++] = arr[index];
}

void pop(int* queue, int* arr, int* front, int index){
    if(arr[index] != queue[*front]) return;
    (*front)++;
}

int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize){
    *returnSize = numsSize - k + 1;
    int front = 0;
    int back = 0;
    int* queue = (int*)malloc(sizeof(int) * numsSize);
    int i = 0;
    while(i < k){
        push(queue, nums, &back, &front, i);
        i++;
    }
    int* res = (int*)malloc(sizeof(int) * (*returnSize));
    int j = 0;
    res[j++] = queue[front];
    //窗口最后一个元素下标为i,将要移除的元素下标为i - k
    while(i < numsSize){
        pop(queue, nums, &front, i - k);
        push(queue, nums, &back, &front, i);
        res[j++] = queue[front];
        i++;
    }
    return res;
}

时间复杂度:O(n),空间复杂度:O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值