import leetcode4.test.MonotonicQueue;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
<p>给你一个整数数组 <code>nums</code>,有一个大小为 <code>k</code><em> </em>的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 <code>k</code> 个数字。滑动窗口每次只向右移动一位。</p>
<p>返回 <em>滑动窗口中的最大值 </em>。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<b>输入:</b>nums = [1,3,-1,-3,5,3,6,7], k = 3
<b>输出:</b>[3,3,5,5,6,7]
<b>解释:</b>
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 <strong>3</strong>
1 [3 -1 -3] 5 3 6 7 <strong>3</strong>
1 3 [-1 -3 5] 3 6 7 <strong> 5</strong>
1 3 -1 [-3 5 3] 6 7 <strong>5</strong>
1 3 -1 -3 [5 3 6] 7 <strong>6</strong>
1 3 -1 -3 5 [3 6 7] <strong>7</strong>
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<b>输入:</b>nums = [1], k = 1
<b>输出:</b>[1]
</pre>
<p> </p>
<p><b>提示:</b></p>
<ul>
<li><code>1 <= nums.length <= 10<sup>5</sup></code></li>
<li><code>-10<sup>4</sup> <= nums[i] <= 10<sup>4</sup></code></li>
<li><code>1 <= k <= nums.length</code></li>
</ul>
<div><div>Related Topics</div><div><li>队列</li><li>数组</li><li>滑动窗口</li><li>单调队列</li><li>堆(优先队列)</li></div></div><br><div><li>???? 1573</li><li>???? 0</li></div>
*/
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
//通过队列来维持窗口,通过单调栈来维持队列的值
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){
window.push(nums[i]);
}else{
window.push(nums[i]);
res.add(window.max());
window.pop(nums[i-k+1]);
}
}
int[] arr = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
arr[i] = res.get(i);
}
return arr;
}
}
class MonotonicQueue{
LinkedList<Integer> q = new LinkedList<>();
void push(int n){
while(!q.isEmpty() && q.getLast() < n){
q.pollLast();
}
q.addLast(n);
}
int max(){
return q.getFirst();
}
void pop(int n){
if(n == q.getFirst()){
q.pollFirst();
}
}
}
//leetcode submit region end(Prohibit modification and deletion)
不会,我可以学;落后,我可以追赶;跌倒,我可以站起来!