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].
[分析] 首先要正确理解题意,结果是返回每个长度为k的窗口中的最大值。当窗口滑动一格时如何确定窗口中的最大值呢?直接的方法是遍历,则复杂度是O(k * n),选用最大堆存储窗口,则找到当前堆中最大值时O(1),窗口滑动时,需要添加一个新元素并删除窗口左边界元素,耗费为O(logk),因此总的复杂度是O(n*logk),当k很大时效率提升比较明显
更优的思路是使用Deque, 时间复杂度为O(N),之前都没用过这种数据结构,JDK文档上说ArrayDeque用作stack时比Stack数据结构快,用作queue时比LinkedList快,好东西呀~
参考
https://leetcode.com/discuss/46578/java-o-n-solution-using-deque-with-explanation
// Method 2: O(N), using Deque
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0)
return new int[0];
int n = nums.length;
int[] max = new int[n - k + 1];
int idx = 0;
Deque<Integer> deque = new ArrayDeque<Integer>();
for (int i = 0; i < n; i++) {
if (!deque.isEmpty() && deque.peek() == i - k)
deque.pollFirst();
while (!deque.isEmpty() && nums[deque.peekLast()] <= nums[i])
deque.pollLast();
deque.offer(i);
if (i >= k - 1) max[idx++] = nums[deque.peek()];
}
return max;
}
// Method 1: O(N * logk), using PriorityQueue
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null)
return null;
if (nums.length == 0)
return new int[0];
int n = nums.length;
int[] result = new int[n - k + 1];
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, new LargerComparator());
for (int i = 0; i < k; i++) {
maxHeap.offer(nums[i]);
}
result[0] = maxHeap.peek();
int start = 0;
for (int i = k; i < n; i++) {
maxHeap.offer(nums[i]);
maxHeap.remove(nums[start++]);
result[i - k + 1] = maxHeap.peek();
}
return result;
}
}
class LargerComparator implements Comparator<Integer> {
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
分享到:
相关推荐
c c语言_leetcode题解之0239_sliding_window_maximum
滑动窗口的最大值(Maximum_value_of_sliding_window.java) 包含min函数的栈(The_stack_containing_the_min_function.java) 队列的最大值(The_maximum_value_of_the_queue.java) 堆(heap_items) ...
leetcode信封 LeetCode LeetCode解题 源码目录 //main下为源码,test下为单元测试 │ src │ ├─main │ └─java │ └─com │ └─algorithm │ GeneratorParenthesis.java //22. ...Sliding Window Maximum
318| [Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) | [C++](./C++/maximum-product-of-word-lengths.cpp) [Python](./Python/maximum-product-of-word-...
LeetCode中的回溯法(Backtracking)和滑动窗口最大值(Sliding Window Maximum)等题目的解决方案常涉及栈和队列。 4. 哈希表:哈希表是一种通过键值对进行高效查找的数据结构。Java中的HashMap类提供了快速的插入...
Maximum 255. Verify Preorder Sequence in Binary Search Tree 907. Sum of Subarray Minimums 二叉搜索树 99. Recover Binary Search Tree 109. Convert Sorted List to Binary Search Tree 116. Populating Next ...
6. **滑动窗口最大值/最小值**:“滑动窗口最大值”(Sliding Window Maximum),使用双端队列和哈希表可以高效地找到每个窗口内的最大值。 7. **组合优化问题**:如“组合总和”(Combination Sum),哈希表可以...
leetcode双人赛 1. Pattern: Sliding Window,滑动窗口类型 滑动窗口类型的题目经常是用来执行数组或是链表上某个区间(窗口)上的操作。比如找最长的全为1的子数组长度。滑动窗口一般从第一个元素开始,一直往右边...
5. **Sliding Window Maximum**:这是一个滑动窗口最大值问题,要求在不断移动窗口时,找到每个窗口内的最大值。可以使用单调栈或双端队列(deque)来解决。 6. **Factorial Trailing Zeroes**:该问题涉及到数学...
例如,"滑动窗口最大值"(Sliding Window Maximum)需要找出数组中每个指定宽度窗口的最大值。 5. **哈希表**:哈希表提供了快速查找功能,常见于解决查找、计数、去重等问题。"两数之和"(Two Sum)也可以用哈希表...
- 滑动窗口最大值:在滑动窗口内维护一个最大值,如LeetCode题目《Sliding Window Maximum》。 - Dijkstra最短路径算法:用于寻找图中节点间的最短路径。 - Huffman编码:在数据压缩中构建最优的Huffman树。 5. ...
而“Sliding Window Maximum”问题则需要我们理解队列的特性,找出数组中每个固定窗口大小的最大值。 二叉树问题在LeetCode中占据了相当大的比重,如“Binary Tree Inorder Traversal”要求中序遍历二叉树。学习...
2. **Sliding Window Maximum**:找到数组中每个滑动窗口的最大值,可以使用队列来快速找到每个窗口的最大值。 ### 递归 递归是一种解决问题的方法,它通过调用自身来解决问题。递归通常用于解决树形结构的问题、...