思路
(1)同题:LeetCode-Heap-239-H:滑动窗口最大值
(2)暴力解法。注意结果数组的大小,第二层循环的控制方法。
(3)双端队列。
解法1-暴力
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0){
return new int[0];
}
int len = nums.length - k + 1;
int[] res = new int[len];
for(int i = 0; i < len; i++){
int max = nums[i];
for(int j = i; j < i + k; j++){
if(nums[j] > max){
max = nums[j];
}
}
res[i] = max;
}
return res;
}
}
解法2-暴力法的优化
(1)参见:不使用数据结构,双100%—— by 来给生活比个耶!
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0){
return new int[0];
}
int len = nums.length - k + 1;
int[] res = new int[len];
int max = Integer.MIN_VALUE;
int maxIndex = -1;
for(int i = 0; i < len; i++){
if(maxIndex >= i && maxIndex < i + k ){
if(nums[i + k - 1] > max){
max = nums[i + k - 1];
maxIndex = i + k - 1;
}
}else{
max = nums[i];
for(int j = i; j < i + k; j++){
if(nums[j] > max){
max = nums[j];
maxIndex = j;
}
}
}
res[i] = max;
}
return res;
}
}
解法3-双端队列
(1)单调递减的双端队列,使得队列头部永远保持为滑动窗口的最大元素,便于后续构造res数组;
(2)queue中存储的是数组索引;
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length <= 0){
return new int[0];
}
int len = nums.length - k + 1;
int[] res = new int[len];
Deque<Integer> queue = new ArrayDeque<>();
int j = 0;
for(int i = 0; i < nums.length; i++){
// 如果新增元素大于队列中的某一个元素,则将该元素先移除
while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){
queue.pollLast();
}
// 窗口元素满了之后,就向右移动
while(!queue.isEmpty() && queue.peek() < i - k + 1){
queue.poll();
}
// 正常添加元素
queue.offer(i);
// 添加到结果数组中
if(i >= k - 1){
res[j++] = nums[queue.peek()];
}
}
return res;
}
}