239. 滑动窗口最大值
困难题是真的困难
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
所以其实不是自己不理解,是没有对索引有深刻的认知。其实思路是正确的,实现起来也很朴素。就是需要自己消化一下。
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号