一、题目描述
二、思路
遍历滑动窗口内整数数组,按顺序创造一个单调递减队列(不需要对整数数组进行排序,直接按原数组顺序遍历下去就行),当遍历到的元素小于等于队列中入口元素,则将该元素放入队列;当遍历到的元素大于队列中入口元素,弹出入口元素直至入口元素大于等于该元素:
当滑动窗口移动时,若要移除的元素的值等于出口元素的值,则弹出出口元素,若不等则不作操作;若要进入窗口的元素的值小于等于入口元素,则直接放入队列,若大于入口元素,则弹出入口元素直至入口元素大于等于该元素:
三、解题过程
-
实现元素放入队列接口函数
- 若要进入窗口的元素的值小于等于入口元素,则直接放入队列,若大于入口元素,则弹出入口元素直至入口元素大于等于该元素:
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)。