转载请标明出处http://www.cnblogs.com/haozhengfei/p/a14049ec0869a8125a69f3af37471c77.html
滑动窗口练习题
第8节 滑动窗口练习题
有一个整型数组 arr 和一个大小为 w 的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。 返回一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值。 以数组为[4,3,5,4,3,3,6,7],w=3为例。因为第一个窗口[4,3,5]的最大值为5,第二个窗口[3,5,4]的最大值为5,第三个窗口[5,4,3]的最大值为5。第四个窗口[4,3,3]的最大值为4。第五个窗口[3,3,6]的最大值为6。第六个窗口[3,6,7]的最大值为7。所以最终返回[5,5,5,4,6,7]。
给定整形数组arr及它的大小n,同时给定w,请返回res数组。保证w小于等于n,同时保证数组大小小于等于500。
测试样例:
[4,3,5,4,3,3,6,7],8,3
返回:[5,5,5,4,6,7]
您的代码已保存
答案正确:恭喜!您提交的程序通过了所有的测试用例
答案正确:恭喜!您提交的程序通过了所有的测试用例
代码示例
1 package com.hzf.stack$queue; 2 3 /** 4 * 有一个整型数组 arr 和一个大小为 w 的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。 5 * 返回一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值。 6 * 以数组为[4,3,5,4,3,3,6,7],w=3为例。因为第一个窗口[4 7 * ,3,5]的最大值为5,第二个窗口[3,5,4]的最大值为5,第三个窗口[5,4, 8 * 3]的最大值为5。第四个窗口[4,3,3]的最大值为4。第五个窗口[3,3 9 * ,6]的最大值为6。第六个窗口[3,6,7]的最大值为7。所以最终返回[5,5,5,4,6,7]。 10 * 11 * 给定整形数组arr及它的大小n,同时给定w,请返回res数组。保证w小于等于n,同时保证数组大小小于等于500。 12 * 13 * 测试样例: [4,3,5,4,3,3,6,7],8,3 返回:[5,5,5,4,6,7] 14 * 15 * @author hzf 16 * 17 */ 18 public class SlideWindow { 19 public int[] slide(int[] arr, int n, int w) { 20 //result数组中保存每个窗口状态下的最大值 21 int[] result = new int[n-w+1]; 22 23 //记录双端队列队头的下标 ,队尾下标 24 int[] qmax = new int[n]; 25 int front = 0, back = 0; 26 27 //j 标记是否达到窗口大小,同时记录result中下一个应该放入的元素的下标 28 int j = 0; 29 30 for(int i=0; i<n; i++){ 31 32 while(front < back && arr[qmax[back-1]] < arr[i])//back为当前要往qmax中放入的值 33 back--; 34 qmax[back++] = i; 35 36 if(j+w-1 == i){ 37 //达到窗口长度 38 result[j] = arr[qmax[front]]; 39 j++; 40 } 41 /** 42 * 保证qmax中front所代表的索引不会过期, 43 * 这个索引的边界就是:qmax[front]+w-1 == i,满足这个条件front++,否则下一窗口就会过期 44 * 比如 45 * front back 46 * qmax 6 8 47 * arr 11 5 48 * 当窗口大小w==3时,假设此时result[j]取arr[qmax[front]],front没有更新, 49 * 如果下一次的arr[9] = 4,那么有如下 50 * front back 51 * qmax 6 8 9 52 * arr 11 5 4 53 * 此时如果在上一步中没有更新front,那么此时窗口[7,8,9]的最大值取的是arr[qmax[6]],显然6已经过期 54 * 55 * 所以综上所述,一旦qmax[front]所代表的索引达到该索引所能控制的边界,front++,以防下一次该front已经过期 56 */ 57 if(qmax[front]+w-1 == i){ 58 //队头过期 59 front++; 60 } 61 } 62 return result; 63 } 64 }