程序媛詹妮弗
终身学习

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. Return the max sliding window.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7] 
Explanation: 

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

 

 

题意:

给定一个长度为k的滑动窗口不断从左往右滑动,给出过程中的各个最大值。

 

思路:

使用一个每次能取出极值的数据结构,TreeMap,如下图,其底层用BST来储存

 

TreeMap要求key必须是比较大小(自然排序或定制排序)

以[1,1,-1,-3,5,3,6,7], k = 3 为例, 遍历数组,将数组每个元素作为TreeMap的key, 将该元素出现频率作为对应value

[1,  1,   -1,   -3,  5,  3,  6,  7] 

 ^ i = 0

[1,  1,   -1,   -3,  5,  3,  6,  7] 

         ^ i = 1

 

[1,  1,   -1,   -3,  5,  3,  6,  7] 

                   ^   i = 2

 

[1,  1,   -1,   -3,  5,  3,  6,  7] 

                              ^  i = 3 此时 i >= k  则先将a[i-k]在TreeMap中对应的出现频率(value) 减1 

                                                         再check一下 a[i-k]对应的value是否为0,为0则直接删去。

 

此例中,a[i-k] = 1, 在TreeMap中对应的value为2,那么value减1 后为1, 仍然继续保留。

 

由此可以看出,大体思路是用TreeMap维护一个所有value值相加为K的BST

用lastKey()来取出当前TreeMap里最大值(根据BST性质,最大值一定在最右)

 

代码:

 1 class Solution {
 2     public int[] maxSlidingWindow(int[] a, int k) {
 3         // corner case
 4         if(k <= 0) return new int[]{};
 5         //TreeMap要求其key必须可比较大小
 6         TreeMap<Integer, Integer> map = new TreeMap<>((o1,o2) -> o1 - o2);
 7         int[] result = new int[a.length - k + 1];
 8         
 9         for(int i = 0; i < a.length; i++){
10             // 1. add to bst
11             if(map.containsKey(a[i])){
12                 map.put(a[i], map.get(a[i]) + 1 );
13             }else{
14                 map.put(a[i], 1);
15             }         
16             // 2. remove from bst when window sliding
17             if( i >= k){
18                 map.put(a[i - k] , map.get(a[i - k]) - 1 );
19                 if(map.get(a[i - k]) == 0 ){
20                     map.remove(a[i - k]);
21                 }
22             }            
23             // 3. get max
24             if( i + 1 >= k){
25                 result[ i - (k - 1)] = map.lastKey();
26             }           
27         }
28         return result;       
29     }

 

posted on 2018-06-16 03:42  程序媛詹妮弗  阅读(213)  评论(0编辑  收藏  举报