题目(难度:困难):
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
input:[2,3,4,2,6,2,5,1]
output:[4,4,6,6,6,5]
代码思想:
由于窗口不断更新,不能一直以一个最大值作为比较器,来确定最大值。这里通过数组下标来辅助最大值maxNum来确定最大值是否失效——最大值和最大值下标同时更新。具体来说:
- 如果下标小于当前数组移动指针,则需要验证新的窗口最大值;
- 如果小标大于等于当前移动指针,则直接取最大值manNum即可。
代码实现:
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || k <= 0 || k > nums.length) return new int[]{};
int[] res = new int[nums.length - k + 1];
int maxVal = Integer.MIN_VALUE;
int maxIndex = 0;
int i = 0, j = 0;
for (; j < k; j++) {
if (nums[j] > maxVal) {
maxVal = nums[j];
maxIndex = j;
}
}
res[i++] = maxVal;
for (; j < nums.length; j++, i++) {
if (nums[j] >= maxVal) {
maxVal = nums[j];
maxIndex = j;
res[i] = maxVal;
continue;
}
if (maxIndex >= i) {
res[i] = maxVal;
continue;
}
if (maxIndex < i) {
maxVal = Integer.MIN_VALUE;
for (int l = j; l >= i; l--) {
if (nums[l] > maxVal) {
maxVal = nums[l];
maxIndex = l;
}
}
res[i] = maxVal;
}
}
return res;
}
测试用例:
算法分析:
时间复杂度O(n),额外空间复杂度O(n)