滴滴,今天冬至,记得吃饺子哦~
吃完饺子,就开始刷题咯~
一、题目
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
二、示例:
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
三、题解
public static int[] maxSlidingWindow(int[] nums, int k) {
//思路一,超时
//Stack<Integer> stack = new Stack<>();
//int[] newNums = new int[nums.length - k + 1];
//int count = 0;
//int skip = -1;
//for (int i = 0; i < nums.length; i++) {
// skip++;
// if (skip != k) {
// if (stack.empty()) {
// stack.push(nums[i]);
// } else {
// int num = stack.pop();
// int max = num > nums[i] ? num : nums[i];
// stack.push(max);
// }
// } else {
// newNums[count++] = stack.pop();
// i -= k;
// skip = -1;
// }
//}
//newNums[count] = stack.pop();
//return newNums;
//思路二
MyQue que = new MyQue();
int[] res = new int[nums.length - k + 1];
int count = 0;
//先装入前k个数字,这里要遵循:大于等于的,弹出上一个,小于的入队列
for (int i = 0; i < k; i++) {
que.push(nums[i]);
}
//找到第一个最大值
int max = que.font();
res[count++] = max;
for (int i = k; i < nums.length; i++) {
//添加
que.push(nums[i]);
//删除
que.del(nums[i - k]);
//取最大值
res[count++] = que.font();
}
return res;
}
}
class MyQue {
Deque<Integer> deque = new LinkedList<>();
//添加,添加规则:当加入数字大于它前面的数时,要把他们都删掉
public void push(int num) {
while (!deque.isEmpty() && num > deque.getLast()) {
deque.removeLast();
}
deque.addLast(num);
}
//font,获取当前队列的头,即获取当前窗口的最大值
public int font() {
return deque.getFirst();
}
//删除数字,窗口滑动,我们只维护当前窗口的值得个数,当有新的数字添加进来时
//我们要将窗口尾部得值删除,因此这里删除时,要传入窗口尾部得值,看是否已被弹出
//如果没有得话,则要删除
public void del(int num) {
Integer first = deque.getFirst();
if (first == num) {
deque.removeFirst();
}
}