239. 滑動視窗最大值

HOJEST發表於2024-07-18

困難題是真的困難

1.首先假設接受了這個想法:維護一個排序好的最大值列表,每次右移彈出所有,比新加入陣列小的數字。、

我自己寫下來的疑問是:
如果右移,需要判斷左邊移除的數字是否是已經儲存的內容,如果有,需要pop。我的想法就是遍歷尋找,因為也不知道這個數字的位置啊,移除的元素也不一定是最大值,不能每次都移除最大值。

需要判斷右邊進來的數字,彈出所有比他小的內容。是怎麼樣簡潔做到這兩點的?每次就算遍歷一遍也很慢。

2.接下來分析題解的觀點

儲存的不是數字,是索引。

小疑問:不還是要判斷這兩點嗎?

分析一下題解程式碼:

 1 from collections import deque
 2 
 3 class Solution:
 4     def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
 5         q = deque()
 6         max_list = []
 7         
 8         for i, num in enumerate(nums):
 9             # Remove indices that are out of the current window
10             while q and q[0] < i - k + 1:
11                 q.popleft()
12             
13             # Remove indices whose corresponding values are less than the current number
14             while q and nums[q[-1]] < num:
15                 q.pop()
16             
17             # Add the current index to the deque
18             q.append(i)
19             
20             # If our window has hit size k, append the current max to the output list
21             if i >= k - 1:
22                 max_list.append(nums[q[0]])
23                 
24         return max_list

解答一下之前的疑惑:

如果儲存的是數字,便不能有自動排序的這個功能了(index從小到大一次排列)。當右移的時候,如果儲存的是index,因為新增最大值進來的時候,總是從右邊新增,左index恆小於右index。所以刪除元素的時候,會更加方便。直接判斷最左邊這個是不是小於i-k+1就可以了。可以減少去尋找這個值的麻煩。

右邊這點,尋找的過程也是一樣的,需要一直遍歷,沒啥好說的。最重要的思想,自己沒有想到的是,刪除左端元素,使用索引會不需要進行遍歷,直接pop最左邊的就行。我覺得每次其實也只需要看看是不是要pop(0),因為只用移除一個元素。修改一版,確實是可以的(忽略一開始想的分段處理,分段也是OK的):

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        max_list = []
        q = []
        for i in range(len(nums)):
            # if i < k:
            #     while q and q[0] < i-k+1:
            #         q.pop(0)
            #     while q and nums[q[-1]] < nums[i]:
            #         q.pop()
            #     q.append(i)
            #     if i == k-1:
            #         max_list.append(nums[q[0]])
            # else:
            if q and q[0] == i-k:
                q.pop(0)
            while q and nums[q[-1]] < nums[i]:
                q.pop()
            q.append(i) 
            if i>k-2:   
                max_list.append(nums[q[0]])
        return max_list

所以其實不是自己不理解,是沒有對索引有深刻的認知。其實思路是正確的,實現起來也很樸素。就是需要自己消化一下。

相關文章