题目描述
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: 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
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
转自:
作者:jyd
链接:https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/solution/mian-shi-ti-59-i-hua-dong-chuang-kou-de-zui-da-1-6/
暴力
class Solution {
public int [ ] maxSlidingWindow ( int [ ] nums, int k) {
if ( nums== null || nums. length == 0 ) {
return new int [ 0 ] ;
}
int [ ] ans = new int [ nums. length - k + 1 ] ;
int count = 0 ;
int i = 0 ; int j = k - 1 ;
while ( j< nums. length) {
int max = findMax ( nums, i, j) ;
i++ ; j++ ;
ans[ count++ ] = max;
}
return ans;
}
public int findMax ( int [ ] nums, int i, int j) {
int max = Integer. MIN_VALUE;
for ( int k = i; k<= j; k++ ) {
max = Math. max ( max, nums[ k] ) ;
}
return max;
}
}
单调栈,栈内单调递减,采用双端队列deque来实现。
class Solution {
public int [ ] maxSlidingWindow ( int [ ] nums, int k) {
if ( nums. length == 0 || k == 0 ) return new int [ 0 ] ;
Deque< Integer> deque = new LinkedList < > ( ) ;
int [ ] res = new int [ nums. length - k + 1 ] ;
for ( int j = 0 , i = 1 - k; j < nums. length; i++ , j++ ) {
if ( i > 0 && deque. peekFirst ( ) == nums[ i - 1 ] )
deque. removeFirst ( ) ;
while ( ! deque. isEmpty ( ) && deque. peekLast ( ) < nums[ j] )
deque. removeLast ( ) ;
deque. addLast ( nums[ j] ) ;
if ( i >= 0 )
res[ i] = deque. peekFirst ( ) ;
}
return res;
}
}
推荐写法,提前将初始窗口赋值好,避免过多判断。
class Solution {
public int [ ] maxSlidingWindow ( int [ ] nums, int k) {
if ( nums. length == 0 || k == 0 ) return new int [ 0 ] ;
Deque< Integer> deque = new LinkedList < > ( ) ;
int [ ] res = new int [ nums. length - k + 1 ] ;
for ( int i = 0 ; i < k; i++ ) {
while ( ! deque. isEmpty ( ) && deque. peekLast ( ) < nums[ i] )
deque. removeLast ( ) ;
deque. addLast ( nums[ i] ) ;
}
res[ 0 ] = deque. peekFirst ( ) ;
for ( int i = k; i < nums. length; i++ ) {
if ( deque. peekFirst ( ) == nums[ i - k] )
deque. removeFirst ( ) ;
while ( ! deque. isEmpty ( ) && deque. peekLast ( ) < nums[ i] )
deque. removeLast ( ) ;
deque. addLast ( nums[ i] ) ;
res[ i - k + 1 ] = deque. peekFirst ( ) ;
}
return res;
}
}