滑動視窗的最大值(java版)
阿新 • • 發佈:2019-02-01
【題目描述】給定一個數組和滑動視窗的大小,找出所有滑動窗口裡數值的最大值。例如,如果輸入陣列{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】暴力法
//1. 遍歷求出每個滑動視窗
//2. 在每個滑動視窗中求出最大值,記錄下來。
//3. 注意邊界情況的處理,如:輸入的陣列為null,或者為空;滑動視窗的大小為零,或者大於陣列長度等。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> arr = new ArrayList<Integer>();
if(num==null || num.length==0 || size==0){
return arr;
}
int len=num.length, inx=0 , end=len-1;
if(size>len){
return arr;
}else if(size==len){
arr.add(maxNum(num, 0, len-1));
}else{
for(int i=0; i<len; i++){
inx = i;
end = inx+size-1;
if(end >= len){
break ;
}else{
arr.add(maxNum(num, inx, end));
}
}
}
return arr;
}
//求幾個值中的最大值
public int maxNum(int[] num, int inx, int end){
int max = num[inx];
for(int i=inx; i<=end; i++){
if(num[i]>max){
max = num[i];
}
}
return max;
}
}
【解題思路2】
//1. 滑動視窗應當是佇列,但為了得到滑動視窗的最大值,佇列序可以從兩端刪除元素,因此使用雙端佇列。
//2. 對新來的元素k,將其與雙端佇列中的元素相比較, 前面比k小的,直接移出佇列(因為不再可能成為後面滑動視窗的最大值了!
//3. 前面比k大的X,比較兩者下標,判斷X是否已不在視窗之內,不在了,直接移出佇列。佇列的第一個元素是當前滑動視窗中的最大值
【實現一】
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> ret = new ArrayList<>();
if (num == null) {
return ret;
}
if (num.length < size || size < 1) {
return ret;
}
LinkedList<Integer> indexDeque = new LinkedList<>();
for (int i = 0; i < size - 1; i++) {
while (!indexDeque.isEmpty() && num[i] > num[indexDeque.getLast()]) {
indexDeque.removeLast();
}
indexDeque.addLast(i);
}
for (int i = size - 1; i < num.length; i++) {
while (!indexDeque.isEmpty() && num[i] > num[indexDeque.getLast()]) {
indexDeque.removeLast();
}
indexDeque.addLast(i);
if (i - indexDeque.getFirst() + 1 > size) {
indexDeque.removeFirst();
}
ret.add(num[indexDeque.getFirst()]);
}
return ret;
}
【實現二】
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> res = new ArrayList<>();
if(size == 0) return res;
int begin;
ArrayDeque<Integer> q = new ArrayDeque<>();
for(int i = 0; i < num.length; i++){
begin = i - size + 1;
if(q.isEmpty())
q.add(i);
else if(begin > q.peekFirst())
q.pollFirst();
while((!q.isEmpty()) && num[q.peekLast()] <= num[i])
q.pollLast();
q.add(i);
if(begin >= 0)
res.add(num[q.peekFirst()]);
}
return res;
}