Sliding Window Maximum [#67]

A long array A[] is given to you. There is a sliding window of size w which is moving from the very left of the array to the very right. You can only see the w numbers in the window. Each time the sliding window moves rightwards by one position.

Following is an example:The array is [1 3 -1 -3 5 3 6 7], and w is 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

Input: A long array A[], and a window width w
Output: An array B[], B[i] is the maximum value of from A[i] to A[i+w-1]

Answer: The obvious solution with run time complexity of O(nw) is definitely not efficient enough. Every time the window is moved, we have to search for the maximum from w elements in the window.

We need a data structure where we can store the candidates for maximum value in the window and discard the element, which are outside the boundary of window. For this, we need a data structure in which we can edit at both the ends, front and back. Deque is a perfect candidate for this problem.

We are trying to find a way in which, we need not search for maximum element among all in the window. We will make sure that the largest element in the window would always appear in the front of the queue.

While traversing the array in forward direction if we find a window where element A[i] > A[j] and i > j, we can surely say that A[j], will not be the maximum element for this and succeeding windows. So there is no need of storing j in the queue and we can discard A[j] forever.

For example, if the current queue has the elements: [4 13 9], and a new element in the window has the element 15. Now, we can empty the queue without considering elements 4, 13, and 9, and insert only element 15 into the queue.

 public static Integer[] getMaxInSlideWindow(Integer[] A, Integer w) {
     // invalid input
     if (A == null || w <= 0 || A.length - w < 0) return null;

     Integer[] B = new Integer[A.length - w + 1];

     // auxiliary queue that is sorted in descending order
     LinkedList<Integer> q = new LinkedList<Integer>();

     for (int i = 0; i < A.length; i++) {
         // enqueue. Remove those smaller values
         int data = A[i];
         while (!q.isEmpty() && q.getLast() < data) {
             q.removeLast();
         }
         q.add(data);

         if (i < w - 1) continue; 

         // dequeue. If the current number is the maximum. Also remove it
         // from the queue
         B[i - w + 1] = q.get(0);
         if (A[i - w + 1] == B[i - w + 1]) {
             q.removeFirst();
         }
     }

     return B;
 }
The above algorithm could be proven to have run time complexity of O(n). This is because each element in the list is being inserted and then removed at most once. Therefore, the total number of insert + delete operations is 2n.


参考:http://www.leetcode.com/2011/01/sliding-window-maximum.html

http://tech-queries.blogspot.com/2011/05/sliding-window-maximum.html

http://www.sureinterview.com/shwqst/897001

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值