题干
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例:
输入: 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
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
进阶:
你能在线性时间复杂度内解决此题吗?
想法
自然而然地有几个想法:
每移动一次,将这个移动后位置的数的大小和窗口中最大值比较,如果它比最大值大,那么将它更新为最大值。
否则仅仅是放到滑动窗口中
另一个点是:窗口大小有限,需要适时的删除已经过期的元素。
Java代码
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0) {
return new int[0];
}
int[] maxes = new int[nums.length - k + 1];
int i, j;
int maxPos = -1;
for (i = 0; i <= nums.length - k; ++i) {
// Ending index of the current window
j = i + k - 1;
// new element >= max of last window
// that means new element is max in the two windows
// here using >= to make maxPos stay in the windows for a longer time
if (maxPos != -1 && nums[j] >= nums[maxPos]) {
maxPos = j;
maxes[i] = nums[maxPos];
}
// new element < max of last window
// AND the max of last window is also in this window
// => it means the max of the last window is still the max of this window
else if (i <= maxPos) {//因为i比maxpo小,其实就是之前已经比较过了,所以nums[i]也比nums[maxpo]小
maxes[i] = nums[maxPos];
}
// new element < max of last window
// AND the max of last window is not in this window
// So we do not know which element is the max in this window, we have to scan the window to find it
else {
int maxWindow = Integer.MIN_VALUE;
int maxPosWindow = 0;
for (int z = i; z <= j; ++z) {
if (nums[z] > maxWindow) {
maxPosWindow = z;
maxWindow = nums[z];
}
}
maxPos = maxPosWindow;
maxes[i] = nums[maxPos];
}
}
return maxes;
}
}
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums==null||nums.length==0||k<=0){
return new int[0];
}
int len=nums.length;
int[] res=new int[len-k+1];
LinkedList<Integer> dQueue=new LinkedList<>();
for(int i=0;i<len;i++){
//比当前元素小的都弹出
while(!dQueue.isEmpty()&&nums[i]>nums[dQueue.getLast()]){
dQueue.removeLast();
}//加索引,记录位置
dQueue.addLast(i);
if(i-dQueue.getFirst()>=k){
dQueue.removeFirst();
}//过了第一次填满之后,就每移动一次更新一次最大
if(i>=k-1){
res[i-k+1]=nums[dQueue.getFirst()];
}
}
return res;}
}
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length==0) return new int[0];
int res[]=new int[nums.length-k+1];
int max=Integer.MIN_VALUE;
int maxIndex=-1;
for(int i=0;i<=nums.length-k;i++){
if(i<=maxIndex){
if(nums[i+k-1]<max){//只与新来的比
res[i]=max;
}else{
max=nums[i+k-1];
maxIndex=i+k-1;
res[i]=max;
}
}else{//重新寻找
max=Integer.MIN_VALUE;
for(int j=i;j<i+k;j++){
if(nums[j]>max){
max=nums[j];
maxIndex=j;
}
}
res[i]=max;
}
}
return res;
}
}
来源:CSDN
作者:宰了那只汤姆猫
链接:https://blog.csdn.net/qq_43491066/article/details/103472853