一、題目
給定一個數組和滑動窗口的大小,找出所有滑動窗口里數值的最大值。例如,如果輸入數組{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 package algorithm7; 2 3 import java.util.ArrayList; 4 import java.util.LinkedList; 5 //使用雙端隊列 6 /* 7 對新來的元素k,將其與雙端隊列中的元素相比較 8 * 1)前面比k小的,直接移出隊列(因為不再可能成為后面滑動窗口的最大值了!), 9 * 2)前面比k大的X,比較兩者下標,判斷X是否已不在窗口之內,不在了,直接移出隊列 10 * 隊列的第一個元素是滑動窗口中的最大值*/ 11 public class MaxInWindows64 { 12 public static void main(String[] args) { 13 int[] num = {2,3,4,2,6,2,5}; 14 ArrayList<Integer> res = maxInWindows(num,3); 15 for(int i : res){ 16 System.out.print(i + " "); 17 } 18 } 19 public static ArrayList<Integer> maxInWindows(int [] num, int size){ 20 ArrayList<Integer> res = new ArrayList<>(); 21 if(size == 0 || size > num.length) 22 return res; 23 int begin; 24 LinkedList<Integer> q = new LinkedList<>(); 25 //先將前size-1個數中的符合條件的值 加入雙端隊列中 26 for(int i = 0; i < size - 1; i++){ 27 while(!q.isEmpty() && num[i] > num[q.getLast()]){ 28 q.removeLast(); 29 } 30 q.addLast(i); 31 } 32 for(int i = size-1; i < num.length; i++){ 33 while(!q.isEmpty() && num[i] > num[q.getLast()]){ 34 q.removeLast(); 35 } 36 q.addLast(i); 37 if(i-q.getFirst()+1 > size) 38 q.removeFirst(); 39 res.add(num[q.getFirst()]); 40 } 41 return res; 42 } 43 }
?