1. 程式人生 > >[leetcode]239. Sliding Window Maximum滑動窗口最大值

[leetcode]239. Sliding Window Maximum滑動窗口最大值

code 數據結構 spa and TE 分享 div pos array

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     }

[leetcode]239. Sliding Window Maximum滑動窗口最大值