滑動視窗法演算法(matlab、java)
阿新 • • 發佈:2018-12-13
這是第一次寫博文,想加強自己對於這方面知識點的理解,雖然演算法很簡單,但是想把自己想法寫下來。
正好看到《劍指offer題目》面試題65:滑動視窗的最大值
給定⼀一個數組和滑動視窗的大⼩,找出所有滑動視窗⾥裡里數值的最⼤大值。例如,如果輸入陣列{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,3,4],2,6,2,5,1}中[2,3,4]三個數最大是4,{2,[3,4,2],6,2,5,1}中[3,4,2]三個數最大是2, {2,3,[4,2,6],2,5,1}中[4,2,6]三個數最大是6, {2,3,4,[2,6,2],5,1}中[2,6,2]三個數最大是6, {2,3,4,2,[6,2,5],1}中[6,2,5]三個數最大是6,{2,3,4,2,6,[2,5,1]}中[2,5,1]三個數最大是5。所以最後滑動視窗的最大值陣列為:{4,4,6,6,6,5}。
下面先展示matlab程式碼段:
clc; clear; a=[2,3,4,2,6,2,5,1]; % a是陣列 w=3; % w是滑動視窗的大小3 len=length(a); % len表示矩陣長度 n=1; c=[]; q=1; for i=n:len-w+1 b=[a(i),a(i+1),a(i+2)]; d=max(b); c(q)=d; q=q+1; n=n+1; end c
java程式碼段:
SlideWindow程式碼塊:
package cn.itcast_06; import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; import java.util.LinkedList; import java.util.List; /** * 返回一個n-w+1 長度的陣列, 每個元素代表每個視窗中的最大值。 */ public class SlideWindow { /** * array:源陣列 * w:視窗大小 * 時間複雜度O(N*w) */ public int[] moveWindow(int[] array, int w) { int[] result = new int[array.length - w + 1]; for (int i = 0; (i + (w - 1)) < array.length; i++) { int[] newArr = Arrays.copyOfRange(array, i, i + w); Arrays.sort(newArr); // 左閉右開 result[i] = newArr[w - 1]; } return result; } /** * 最優解: 時間複雜度為O(N) * 利用雙端佇列 */ public Integer[] moveWindow1(Integer[] arr,int n, int w) { if(w == 1){ return arr; //如果視窗大小為1, 直接返回陣列即可 } Deque<Integer> deq = new LinkedList<>(); //雙端佇列 List<Integer> res = new ArrayList<>(); for(int i=0; i<n; i++){ //如果qmax為空,或者取出當前deque隊尾存放的下標j 滿足 arr[j] > array[i], //直接把下標i放進deque的隊尾. if(deq.isEmpty() || arr[deq.getLast()] > arr[i]){ deq.addLast(i); }else{ //如果arr[j] <= array[i],則一直從deque的隊尾彈出下標。 //直到某個下標在deque中對應的值大於arr[i],就把i放入deque的隊尾。 while(!deq.isEmpty() && arr[deq.getLast()] <= arr[i]){ deq.removeLast(); } deq.addLast(i); } //如果deque隊頭的下標等於i-w,彈出deque當前隊頭下標. if(deq.getFirst() == i-w){ deq.removeFirst(); } //如果w視窗等於3的話,那麼從i=2開始,產生的才是視窗的最大值。 if(i < w-1){ continue; } res.add(arr[deq.getFirst()]); } return (Integer[])res.toArray(new Integer[n-w+1]); } }
主程式程式碼塊:
package cn.itcast_06;
import java.lang.reflect.Array;
public class main {
public static void main(String[] args) {
SlideWindow mw = new SlideWindow();
Integer[] array = new Integer[] { 4, 5, 5, 4, 3, 3, 6, 7, 6, 4, 8, 9, 14 };
Integer[] window = mw.moveWindow1(array, array.length, 3);
System.out.print("[");
for (int x = 0; x < array.length; x++) {
if (x == array.length - 1) {
System.out.print(array[x]);
} else {
System.out.print(array[x] + ", ");
}
}
System.out.println("]");
}
}