• leetcode面试准备:Sliding Window Maximum


    leetcode面试准备:Sliding Window Maximum

    1 题目

    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.

    Hint:

    1. How about using a data structure such as deque (double-ended queue)?
    2. The queue size need not be the same as the window’s size.
    3. Remove redundant elements and the queue should store only elements that need to be considered.

    接口:public int[] maxSlidingWindow(int[] nums, int k)

    2 思路

    1. Brute force solution is O(nw)

    2. Use heap, when window moves, delete the first one in the window, add the next one into the window. The run time complexity is O(n lg w).

    3. Use double-ended queue.

    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.

    3 代码

        // 暴力解法:采用左右边界滑动窗口
    	// Time:O(n*k)
    	public int[] maxSlidingWindow1(int[] nums, int k) {
    		int len = nums.length;
    		if (len == 0)
    			return new int[0];
    		int left = 0, right = k - 1;
    		int[] res = new int[len - k + 1];
    		while (right < len) {
    			res[left] = nums[left];
    			for (int i = left + 1; i <= right; i++) {
    				res[left] = Math.max(res[left], nums[i]);
    			}
    			left++;
    			right++;
    		}
    		return res;
    	}
    
    	// 用TreeSet实现堆,减少查询最大值的效率,降低了复杂度。
    	// Wrong Answer:无法解决重复元素的问题。
    	// Time:O(nlogK) Space:O(k)
    	public int[] maxSlidingWindow2(int[] nums, int k) {
    		int len = nums.length;
    		if (len == 0)
    			return new int[0];
    		int[] res = new int[len - k + 1];
    		TreeSet<Integer> heap = new TreeSet<Integer>();
    		for (int i = 0; i < k - 1; i++) {
    			heap.add(nums[i]);
    		}
    		for (int i = k - 1; i < len; i++) {
    			heap.add(nums[i]);
    			int index = i - k + 1;
    			res[index] = heap.last();
    			heap.remove(nums[index]);
    		}
    		return res;
    	}
    
    	// 用双端队列来解决,时间复杂度降到了O(n)
    	// Time:O(n) Space:O(k)
    	public int[] maxSlidingWindow(int[] nums, int k) {
    		int len = nums.length;
    		if (len == 0)
    			return new int[0];
    		int[] res = new int[len - k + 1];
    		Deque<Integer> dq = new LinkedList<Integer>();
    		for (int i = 0; i < len; i++) {
    			int data = nums[i];
    			while (!dq.isEmpty() && dq.getLast() < data) {
    				dq.removeLast();
    			}
    			dq.add(data);
    			if (i < k - 1) {
    				continue;
    			}
    			int index = i - k + 1;
    			res[index] = dq.getFirst();
    			if (res[index] == nums[index]) {
    				dq.removeFirst();
    			}
    		}
    		return res;
    	}
    

    4 总结

    三种方法解决,如何解决堆储存重复元素的问题。

  • 相关阅读:
    《ASP.NET Core跨平台开发从入门到实战》Web API自定义格式化protobuf
    .NET Core中文分词组件jieba.NET Core
    .NET Core 2.0及.NET Standard 2.0
    Visual Studio 2017 通过SSH 调试Linux 上.NET Core
    Visual Studio 2017 ASP.NET Core开发
    Visual Studio 2017正式版离线安装及介绍
    在.NET Core 上运行的 WordPress
    IT人员如何开好站立会议
    puppeteer(二)操作实例——新Web自动化工具更轻巧更简单
    puppeteer(一)环境搭建——新Web自动化工具(同selenium)
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/4801473.html
Copyright © 2020-2023  润新知