JZ64 滑动窗口的最大值
滑动窗口的最大值
http://www.nowcoder.com/questionTerminal/1624bc35a45c42c0bc17d17fa0cba788
JZ64 滑动窗口的最大值
题目:
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
思路2:标记每个窗口的最大值。
移动窗口时,如果最大值还在窗口内,就跟新加入的值比较,然后再次标记最大值的位置
如果最大值不在窗口内,循环窗口找出最大值
思路2最优时候:每次窗口滑动都遇见最大值,即最大值不会过期,一遍就能找出。O(N)
最差时候,每次都会过期(最大值都是窗口最左边的那个数),每次都要循环遍历(退化成暴力解的情况)。O(K*N), k为窗口大小
//因为和暴力代码写在一块了,所以只有关键部分的代码
//标记每个窗口的最大值。
//移动窗口时,如果最大值还在窗口内,就跟新加入的值比较,然后再次标记最大值的位置
//如果最大值不在窗口内,循环窗口找出最大值
if(size > num.length || size == 0) return new ArrayList();
ArrayList<Integer> list = new ArrayList<Integer>();
int left = 0;
int right = left + size - 1;
//找出第一个窗口的最大值
int max = num[left];
int index = left; //最大值的位置
for(int i=left; i<=right && i<num.length; i++){
if(num[i] > max){
max = num[i];
index = i;
}
}
//先把第一个窗口处理完毕
list.add(max);
left++;
right++;
while(right <= num.length-1){
//判断最大值是否还在窗口内
if(index>=left && index <= right){
//比较窗口内的新值和最大值的大小
if(num[right] >= max){
//等于时候也要更新最大值位置
max = num[right];
index = right;
}
}else{
//重新查找窗口内的最大值
//记得初始化这个窗口的最大值,不然比较的就是以前的值
max = num[left];
for(int i=left; i<=right && i<num.length; i++){
if(num[i] > max){
max = num[i];
index = i;
}
}
}
list.add(max);
left++;
right++;
}
return list; 思路1:暴力
遍历数组,然后每个窗口找出最大值即可(面试估计不行)
暴力代码如下
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size) {
//暴力解应该能行
//1. 暴力
if(size > num.length || size == 0) return new ArrayList();
ArrayList<Integer> list = new ArrayList<Integer>();
int left = 0;
int right = left + size - 1;
while(right <= num.length-1){
int max = num[left];
for(int i=left; i<=right; i++){
if(num[i] > max){
max = num[i];
}
}
list.add(max);
left++;
right++;
}
return list;
}
}
查看10道真题和解析