题目:
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
思路:
思路1:暴力循环法
思路2:
将有可能成为最大值数字的下表放在双端队列deque中,从而减少比较的次数。
由于每个数字都有可能成为滑动窗口内数字的最大值,所以数组中的任何一个元素都会入队列。
算法的关键在于出队列:
1、若下标处于窗口之外,则需要出队列;
2、若后面的元素大于前面的元素,那么前面的元素需要出队列
程序:
程序1:
import java.util.ArrayList;
public class subject64 {
public static ArrayList<Integer> maxInWindows(int[] num, int size){
ArrayList<Integer> arrList = new ArrayList<Integer>();
if(num == null || num.length == 0 || size < 1) {
return arrList;
}
int length = num.length;
int start = 0;
int end = length - 1;
if(size > length) {
return arrList;
}else if(size == length) {
arrList.add(findMax(num, start, end));
}else {
//遍历求出每个滑动窗口
for(int i = 0; i <= length - size; i ++) {
start = i;
end = start + size - 1;
arrList.add(findMax(num, start, end));
}
}
return arrList;
}
//求最大值
public static int findMax(int[] data, int start, int end) {
int max = data[start];
for(int i = start; i <= end; i ++) {
if(max < data[i]) {
max = data[i];
}
}
return max;
}
public static void main(String args[]) {
int[] array = new int[] {2,3,4,2,6,2,5,1};
System.out.println(maxInWindows(array, 3));
}
}
程序2:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
public class subject64 {
//把可能会成为最大值的下标存储下来,从而降低扫描次数
public static int[] maxInWindows(int[] num, int size){
int[] result = new int[num.length - size + 1];
if(num == null || num.length == 0 || size < 1) {
return result;
}
Deque<Integer> deque = new ArrayDeque<>();
for(int i = 0; i < size - 1; i ++) {
if(! deque.isEmpty() && num[deque.getLast()] <= num[i]) {
deque.removeLast();
}
deque.addLast(i);
}
for(int i = size - 1; i < num.length; i ++) {
while(! deque.isEmpty() && i - size + 1 > deque.getFirst()) {
deque.removeFirst();
}
while(! deque.isEmpty() && num[deque.getLast()] <= num[i]) {
deque.removeLast();
}
deque.addLast(i);
result[i - size + 1] = num[deque.getFirst()];
}
return result;
}
public static void main(String args[]) {
int[] array = new int[] {2,3,4,2,6,2,5,1};
int[] result = maxInWindows(array,3);
for(int i=0;i<result.length;i++){
System.out.print(result[i] + ",");
}
}
}