题目描述
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1
输出:[1]
提示:
解法1 暴力破解
js
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
let left=0;
let right=k;
let max=0;
const res=[]
for(let i=0;i<k;i++){
max=Math.max(max,nums[i]);
}
res.push(max)
while(right<nums.length){
//不断地右移
left++;
right++;
max=maxFunc(left,right,nums);
res.push(max);
}
return res;
};
function maxFunc(start,end,numArr){
let max=numArr[start];
while(start<end){
max=Math.max(max,numArr[start]);
start++;
}
return max;
}
执行情况
解法2 滑动窗口+记录最值
js
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
const res=[]
let max=0;
for(let i=0;i<k;i++){
max=Math.max(max,nums[i]);
}
res.push(max);
// left= i-k; //移出的i-k-1
for(let i=k;i<nums.length;i++){
if(nums[i-k]==max){
//移出了最大的值
max=maxFunc(i-k+1,i+1,nums);
}
if(nums[i]>max){
max=nums[i];
}
res.push(max);
}
return res;
};
function maxFunc(start,end,numArr){
let max=numArr[start];
while(start<end){
max=Math.max(max,numArr[start]);
start++;
}
return max;
}
解法3 单调队列
js
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
const n = nums.length;
const q = [];
for(let i=0;i<k;i++){
while(q.length&&nums[i]>=nums[q[q.length-1]]){
q.pop()
}
q.push(i)
}
const res=[nums[q[0]]];
for(let i=k;i<n;i++){
while(q.length&&nums[i] >= nums[q[q.length-1]]){
q.pop();
}
q.push(i)
while(q[0]<=i-k){
q.shift()
}
res.push(nums[q[0]])
}
return res;
};
执行情况