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]
.
题目分析:
对于此题,首先第一反应是把窗口内的元素都存起来,然后来一个删之前的,然后找到窗口内的最大元素,这样时间为o(n*k),然后就在想,有没有更好的办法,怎么样才能快速找到窗口中最大元素,并且能够很好判断是否在窗口范围内。想到可以使用LinkedList将元素的下标按照从大到小排列,当元素个数超过窗口长度的时候,删除第一个元素下标。使用linkedList是因为它添加删除元素方便
源代码如下:
/**
* 使用linkedList存储最大的,次大的,第三大的数字下标
* 当之前的值小于当前值的时候,依次取出来,保证每次都是大的元素靠前面
* 当第一个值已经不再滑动窗口内的时候,删除
* */
public int[] maxSlidingWindow(int[] nums, int k) {
int len=nums.length;
if(len<=0||k<=0) return new int[0];
if(k>len) k=len;
int[] res=new int[len-k+1];
LinkedList<Integer> q=new LinkedList<Integer>();
for(int i=0;i<len;i++)
{
while(!q.isEmpty()&&nums[i]>=nums[q.getLast()])
{
q.removeLast();
}
q.add(i);
if(i-q.getFirst()>=k)
{
q.removeFirst();
}
if(i+1>=k) res[i+1-k]=nums[q.getFirst()];
}
return res;
}