这是第一次写博文,想加强自己对于这方面知识点的理解,虽然算法很简单,但是想把自己想法写下来。
正好看到《剑指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("]");
}
}