mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-11-01 03:23:42 +00:00
Update 59. 滑动窗口的最大值.md
更新大顶堆解法的时间复杂度分析,补充单调队列解法及对应的原理配图与实现代码。
This commit is contained in:
+34
-1
@@ -14,9 +14,11 @@
|
||||
|
||||
## 解题思路
|
||||
|
||||
### 大顶堆
|
||||
|
||||
维护一个大小为窗口大小的大顶堆,堆顶元素即为当前窗口的最大值。
|
||||
|
||||
假设窗口的大小为 M,数组的长度为 N。在窗口向右移动时,需要先在堆中删除离开窗口的元素,并将新到达的元素添加到堆中,这两个操作的时间复杂度都为 log<sub>2</sub>M,因此算法的时间复杂度为 O(Nlog<sub>2</sub>M),空间复杂度为 O(M)。
|
||||
假设窗口的大小为 M,数组的长度为 N。在窗口向右移动时,需要先在堆中删除离开窗口的元素,并将新到达的元素添加到堆中。添加的时间复杂度为 O(logM),但 PriorityQueue.remove(Object) 要先线性查找这个元素,时间复杂度为 O(M),因此算法的时间复杂度为 O(NM),空间复杂度为 O(M),N 和 M 都很大时会超时。
|
||||
|
||||
```java
|
||||
public int[] maxAltitude(int[] heights, int limit) {
|
||||
@@ -38,3 +40,34 @@ public int[] maxAltitude(int[] heights, int limit) {
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
### 单调队列
|
||||
|
||||
用双端队列保存窗口中有可能成为最大值的元素的下标,并让它们对应的值从队头到队尾递减,队头就是当前窗口的最大值:
|
||||
|
||||
- 新元素入队前,从队尾删除所有不大于它的元素:它们比新元素先离开窗口,值又不比它大,以后不可能成为最大值;
|
||||
- 队头的下标离开窗口时,从队头删除。
|
||||
|
||||
每个下标最多入队、出队各一次,时间复杂度为 O(N),空间复杂度为 O(M)。以 {2, 3, 4, 2, 6, 2, 5, 1}、窗口大小 3 为例:
|
||||
|
||||
<div align="center"> <img src="pics/offer59-monotonic-deque.png" width="620px"/> </div><br>
|
||||
|
||||
```java
|
||||
public int[] maxAltitude(int[] heights, int limit) {
|
||||
if (heights == null || heights.length == 0 || limit <= 0) {
|
||||
return new int[0];
|
||||
}
|
||||
int[] ret = new int[heights.length - limit + 1];
|
||||
Deque<Integer> deque = new ArrayDeque<>(); /* 保存下标,对应的值从队头到队尾递减 */
|
||||
for (int i = 0; i < heights.length; i++) {
|
||||
while (!deque.isEmpty() && heights[deque.peekLast()] <= heights[i])
|
||||
deque.pollLast();
|
||||
deque.addLast(i);
|
||||
if (deque.peekFirst() <= i - limit) /* 队头已经离开窗口 [i - limit + 1, i] */
|
||||
deque.pollFirst();
|
||||
if (i >= limit - 1)
|
||||
ret[i - limit + 1] = heights[deque.peekFirst()];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 146 KiB |
Reference in New Issue
Block a user