您的位置:首页 > 其它

[Leetcode] Sliding Window Maximum

2015-09-01 20:25 465 查看
Sliding Window Maximum

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]
.

刚开始想到是使用heap来保存当前遍历过的元素,并且保持最大堆状态,每当达到从堆中取出一个元素,则将当前节点之前的第k个元素从堆中删除,这样堆一直保持k的大小,整体算法的复杂度是O(N*k(logk)),从堆中删除需要找到需要找到节点,时间是O(K),删除O(Log(k)),最多N个节点。

private int[] method2(int []nums,int k){
if(nums.length==0) return nums;
       //递减排序方式
Comparator<Integer> compare = new Comparator<Integer>(){
public int compare(Integer i1,Integer i2){
return i2-i1;
}
};
PriorityQueue<Integer> heap = new PriorityQueue<Integer>(compare);
int [] res = new int[nums.length-k+1];
for(int i=0;i<nums.length;i++){
heap.offer(nums[i]);
if(i>=(k-1)){
res[i-k+1] = heap.peek();
heap.remove(nums[i-k+1]);
}
}
return res;
}
public int[] maxSlidingWindow(int[] nums, int k) {
return method2(nums,k);
}


后来发现使用双端队列,就可以,并且时间复杂度降低到了O(N)

private int[] method1(int[] nums, int k){
if(nums.length==0) return nums;
LinkedList<Integer> dequeue = new LinkedList<Integer>();
int [] res = new int[nums.length-k+1];
for(int i=0;i<nums.length;i++){
int data = nums[i];
//当data等于双端队列当中的最大值的时候,不能讲队列中的元素弹出,
//原因是这个元素可能会被后面的某个元素视为最大元素,当前遇到的这个值虽然和双端队列当中目前的最大值是相等的,但是他出现的比较晚,在后面的窗口当中他可能会被用到。
//举个例子 4444333,如果遇到想的就删除,那么
//4 4 4 4 变为空,遇到3的时候虽然窗口大小为3的窗口中的最大值是4,但是4已经不存在了,关键是在前面已经把他删除了。

while(dequeue.size()!=0&&data>dequeue.getFirst()) dequeue.removeFirst();
dequeue.addFirst(data);
if(i>=k-1){
int largest = dequeue.getLast();
res[i-k+1] = largest;
if(largest==nums[i-k+1]){
dequeue.removeLast();
}
}
}
return res;
}


这里的关键问题是while循环当中为甚me在当前data比队列中的第一个元素相等的时候,会保留相等元素,详细原因看参考代码中的注释。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: