题目
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
Window position Max
[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
Therefore, return the max sliding window as [3,3,5,5,6,7].
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array’s size for non-empty array.
Follow up:
Could you solve it in linear time?
思路
其实这是一道数据结构的题,需要用到双端队列。其实队列的长度上限只需要设置为窗口大小即可。这个双端队列中只需要存,从开始数字向右递增的数字:比如,第一个窗口【1,3,-1】,队列中只需要记录1和3,当窗口右移一个的时候,队列出队剩下3,此时窗口【3,-1,-3】,同样-3不入队。再当窗口右移一个时,队列为空,此时窗口【-1,-3,5】,当对列空的时候,需要从窗口左侧开始将递增的数字依次入队形成新的队列,此时队列中为-1,5.再向右移动,队列出队剩下5,窗口为【-3,5,3】,3不需要入队。再右移,队列成空,此时窗口为【5,3,6】,队列重置为5,6;以此类推,因为每当队列变为空的时候,都要从当前窗口重新加载,因此不会忽略掉任何一个最大值。
代码
public int[] maxSlidingWindow(int[] nums, int k) {
ArrayDeque<Integer> dequeue = new ArrayDeque<Integer>();
List<Integer> arr = new LinkedList<Integer>();
int curIdx = 0;
while(curIdx!=nums.length){
if(dequeue.isEmpty()){
for(int i=0;i<k && curIdx<nums.length;i++){
if(dequeue.isEmpty()){
dequeue.add(nums[curIdx]);
} else{
if(nums[curIdx]>dequeue.peekLast()){
dequeue.add(nums[curIdx]);
}
}
curIdx++;
}
arr.add(dequeue.peekLast());
} else{
dequeue.pollFirst();
if(dequeue.isEmpty()){
for(int i=curIdx-k+1;i<=curIdx;i++){
if(dequeue.isEmpty()){
dequeue.add(nums[i]);
} else{
if(nums[i]>dequeue.peekLast()){
dequeue.add(nums[i]);
}
}
}
} else{
if(nums[curIdx]>dequeue.peekLast()){
dequeue.add(nums[curIdx]);
}
}
arr.add(dequeue.peekLast());
curIdx++;
}
}
int [] rst = new int[arr.size()];
int i=0;
for(Integer I:arr){
rst[i] = I;
i++;
}
return rst;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。