給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。
返回滑動視窗中的最大值。
示例:
暴力求解
最簡單的一種方式就是暴力求解,原理其實很簡單,就是視窗在往右滑動的過程中,每滑動一步就計算視窗內最大的值,就以上面的資料畫個圖來看下
**比較簡單,直接看下
public
int[
]maxslidingwindow
(int
nums,
int k)
res[i]
= max;
}return res;
}
如果看過之前講的378,資料結構-7,堆我們還可以使用堆來解決,這裡可以使用最大堆,堆頂的元素是最大的,因為這題求的就是視窗內的最大值,堆的大小就是視窗的大小。因為堆的每次刪除和新增都會涉及到往下調整和往上調整,所以效率一般不是很高,也可以看下,這裡就是用priorityqueue來代替堆
public
int[
]maxslidingwindow
(int
nums,
int k)
}return res;
}
雙端佇列求解我們知道一般的佇列都是先進先出的,但雙端佇列兩端都可以進出,如果對雙端佇列不熟悉的可以看下之前寫的359,資料結構-3,佇列。
使用雙端佇列首先要搞懂乙個問題,就是在雙端佇列中,要始終保證隊頭是佇列中最大的值。那怎麼保證呢,就是在新增乙個值之前,比他小的都要被移除掉,然後再新增這個值。我們舉個例子,比如視窗大小是3,雙端佇列中依次新增3個值[4,2,5],在新增5之前我們要把4和2給移除,讓佇列中只有乙個5,因為視窗是往由滑動的,當新增5的時候,4和2都不可能再成為最大值了,並且4和2要比5還先出佇列,搞懂了上面的過程我們隨便畫個圖看下
搞懂了上面的過程**就很容易寫了,再看**之前先來看一下雙端佇列常用的幾個函式
**如下
public
int[
]maxslidingwindow
(int
nums,
int k)
//在新增乙個值之前,前面比他小的都要被移除掉,並且還要保證視窗
//中佇列頭部元素永遠是佇列中最大的
while
(!qeque.
isempty()
&& nums[qeque.
peeklast()
]< nums[i]
)//當前元素的下標加入到佇列的尾部
qeque.
addlast
(i);
//當視窗的長度大於等於k個的時候才開始計算(注意這裡的i是從0開始的)
if(i >= k -1)
}return res;
}
兩端掃瞄解決這個不太容易想到,就是根據視窗大小把陣列分成n個視窗,每個視窗分別從左往右和從右往左掃瞄,記錄掃瞄的最大值,就像下面這樣
視窗分好之後乙個從前往後掃瞄乙個從後往前掃瞄,記錄每個視窗掃瞄的最大值。我們取視窗內的最大值的時候,如果視窗在原陣列中開始的下標正好是k的倍數,比如下面這樣,他的最大值很容易找
但如果視窗滑動到下面這種情況下
如果要找這個視窗的最大值,我們就要選視窗內從左邊掃瞄最後乙個和從右邊掃瞄最後乙個(視窗內從左邊數第乙個)的最大值,也就是下面這樣
res[j]
= math.
max(maxright[i]
, maxleft[i + k -1]
);
為什麼要這樣選,大家可以想一下,因為如果選擇從左邊掃瞄的第乙個值的話,那麼這個值可能不是當前視窗內的值,同理從右邊掃瞄的也一樣。
搞懂了上面的分析過程**就很容易寫了
public
int[
]maxslidingwindow
(int
nums,
int k)
//返回的結果值
int[
] res =
newint
[len - k +1]
;for
(int i =
0, j =
0; i < res.length; i++
)return res;
}
總結滑動視窗題,第一種暴力求解一般都能想到,但效率很差,最常見的就是第2種使用雙端佇列,第3種方式效率也挺高的,但一般不太容易想到。
滑動視窗最大值
題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 幾個注意點 利用雙端佇列實現,如果後者比前者大,前者丟擲,後者進,如果比前者小,壓入佇列,判斷隊頭是否過期,這就需...
滑動視窗最大值
給定乙個陣列和滑動視窗的大小,請找出所有滑動視窗裡的最大值。public class 滑動視窗的最大值 if num.length size size 1 用來儲存可能是滑動視窗最大值的數字的下標 linkedlist indexdeque newlinkedlist for int i 0 i s...
滑動視窗最大值
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。返回滑動視窗中的最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大...