思路
滑动窗口 + 遍历
解题思路
基本思路:使用滑动窗口法遍历数组,动态维护当前窗口的最大值。 特殊情况:该方法有一个缺陷,如果出窗口的元素是当前窗口的最大值max时,接下来的窗口中的最大值就无法确定了,所以就需要遍历新窗口,寻找其中的最大值。
复杂度
- 时间复杂度: O(N * K)
- 空间复杂度: O(N)
代码实现:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] maxNum = new int[n - k + 1];
int right = 0;
int max = nums[0]; //记录窗口的最大值
int index = 0; //记录最大值的下标
//初始化窗口
while(right < k){
if(nums[right] >= max){
max = nums[right];
index = right;
}
right++;
}
maxNum[0] = max;
//滑动窗口
while(right < n){
//如果入窗口的元素成为最大值则更新max和index
if(nums[right] >= max){
max = nums[right];
index = right;
}
//如果出窗口的元素为最大值,则需要重新寻找当前窗口的最大值及下标
if(right-k == index){
int[] newMax = findMax(nums,right-k+1,k);
max = newMax[0];
index = newMax[1];
}
maxNum[right - k + 1] = max;
right++;
}
return maxNum;
}
//寻找当前窗口的最大值及其下标
public int[] findMax(int[] nums, int start, int k){
int[] max = new int[2];
max[0] = nums[start];
max[1] = start;
for(int i = start + 1; i < start + k; i++){
if(nums[i] >= max[0]){
max[0] = nums[i];
max[1] = i;
}
}
return max;
}
}
在我第一次写的时候直接就在每个窗口中加findMax函数无脑遍历,运行后发现超时,代码时间复杂度是 O(N * K)。随后按自己想法改了改代码,改成现在这个,最坏时间复杂度还是O(N * K),但是再一次运行发现可以通过。后面看了看官方题解,题解一的思路和我的大致一样但是用了优先级队列,运行速度方面能比自己的快,主要区别在于自己的findMax函数用遍历的方式找最大值及下标,优先级队列底层则用的堆,其复杂度为logN级别。