Sliding Window Maximum

Total Accepted: 22812 Total Submissions: 85476 Difficulty: Hard
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:max heap去求最大,然后指针不断往前走,因为heap删除操作O(k),所以总时间复杂度为O(nk),为下面代码第一个实现
  • 思路2:max hashheap求最大,因为hashheap删除操作O(logk),所以总时间复杂度为O(nlogk)
  • 思路3:使用deque,deque首处就是最大值所在处,如果后面加入的元素更大,就从之前后面poll出去,如果长度超过了k,就把deque首处元素poll出去. 关键之处在于使用deque储存的是Index,而不是元素值本身. 时间复杂度O(n),为下面代码第二个实现

heap实现

public class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {

        int size = nums.length;

        if (size == 0 || k == 0 || size < k) {
            return new int[0];
        }

        int[] result = new int[size - k + 1];
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k, Collections.reverseOrder());

        for (int x = 0; x < k; x++) {
            pq.offer(nums[x]);
        }

        int i = 0;
        int j = k;
        while (j < size) {
            result[i] = pq.peek();
            pq.remove(nums[i++]);
            pq.offer(nums[j++]);
        }
        result[i] = pq.peek();


        return result;
    }
}

deque实现

public class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {

        int size = nums.length;

        if (size == 0 || k == 0 || size < k) {
            return new int[0];
        }
        int[] result = new int[size - k + 1];

        Deque<Integer> deque = new LinkedList<Integer>();
        deque.offer(0);
        int i = 0;
        for (i = 1; i < k; i++) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.getLast()]) {
                deque.removeLast();
            }
            deque.offer(i);
        }

        int index = 0;
        result[index++] = nums[deque.getFirst()];

        while (i < size) {
            if (i - deque.getFirst() >= k) {
                deque.removeFirst();
            }
            while (!deque.isEmpty() && nums[i] >= nums[deque.getLast()]) {
                deque.removeLast();
            }
            deque.offer(i);
            i++;
            result[index++] = nums[deque.getFirst()];
        }

        return result;
    }
}

results matching ""

    No results matching ""