Problem: 239. 滑动窗口最大值
文章目录
- 题目描述
- 思路
- 复杂度
- Code
题目描述
思路
1.编写实现优先队列类:
1.1.实现push(int n):将元素n添加到队列尾,同时将n前面大于n的元素删除
1.2.实现int max():将队列头元素取出(由于实现了push所以此时队列头元素为当前队列中的最大值)
1.3.实现pop(int n):将队列头的元素n删除(代码实现中,需要先检查n是否还在当前对头。因为n有可能已经删除掉了)
2.题目代码逻辑实现:
2.1.生成窗口:将前k个元素添加到实现的优先队列中;
2.2.维护窗口:每次push一个新的元素到窗口,再取出当前窗口中的最大值添加到结果集合中,再删除之前的窗口左侧
复杂度
时间复杂度:
O ( n ) O(n) O(n);其中 n n n为数组nums的长度
空间复杂度:
O ( n ) O(n) O(n);
Code
/* Monotonic queue implementation */
class MonotonicQueue {
LinkedList<Integer> maxq = new LinkedList<>();
public void push(int n) {
// Delete all elements smaller than n
while (!maxq.isEmpty() && maxq.getLast() < n) {
maxq.pollLast();
}
// Then add n to the tail
maxq.addLast(n);
}
public int max() {
return maxq.getFirst();
}
public void pop(int n) {
if (n == maxq.getFirst()) {
maxq.pollFirst();
}
}
}
class Solution {
/***
* Sliding Window Maximum
*
* @param nums Given array
* @param k Given number
* @return int[]
*/
public int[] maxSlidingWindow(int[] nums, int k) {
MonotonicQueue window = new MonotonicQueue();
List<Integer> res = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (i < k - 1) {
// Fill the front k-1 of the window first
window.push(nums[i]);
} else {
// The window slides forward to add a new number
window.push(nums[i]);
// Record the maximum value of the current window
res.add(window.max());
// Remove old numbers
window.pop(nums[i - k + 1]);
}
}
// Needs to be converted to an int[] array and returned
int[] arr = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
arr[i] = res.get(i);
}
return arr;
}
}