我以前有碰到過這種問題,但我沒有在當下把 deque 的觀念內化,都選擇用dp,終於在今天吃苦頭。
(又或者可以用 two pointers 做解決。)
這種類型的問題有一個特色,就是有「連續子陣列(或串列)」,若條件不合,去掉頭再繼續。
用 時間複雜度 O(N) 解決掉,只給跑一次 nums 的機會。
基本架構是用一個串列,先把遇到的數加進串列後方,(while)若 max() - mix() > limit 則 del[0],在每輪最後檢查len()。
基本型(Python) ※會超時
class Solution: def longestSubarray(self, nums, limit) -> int: queue = [] result = 0 for i in range(len(nums)): queue.append(nums[i]) while queue and max(queue) - min(queue) > limit: del queue[0] result = max(result, len(queue)) return result其中最耗費時間的函數是 max() 跟 min() ,如果queue的所含的個數很多,就會在這裡因為一直找而超時。
所以改善這一塊,用兩個變數 maxValue 跟 minValue 去保存最大小值就能順利通過。
改善型(Python)
class Solution: def longestSubarray(self, nums, limit) -> int: queue = [] result = 0 maxValue = minValue = nums[0] for i in range(len(nums)): queue.append(nums[i]) maxValue = max(maxValue, nums[i]) minValue = min(minValue, nums[i]) while queue and maxValue - minValue > limit: v = queue.pop(0) if queue: if v == maxValue: maxValue = max(queue) if v == minValue: minValue = min(queue) else: maxValue = nums[i+1] minValue = nums[i+1] result = max(result, len(queue)) return result
class Solution: def longestSubarray(self, nums, limit) -> int: sp = 0 result = 0 maxValues = [] minValues = [] for i in range(len(nums)): num = nums[i] if not maxValues or num >= maxValues[-1]: maxValues.append(num) if not minValues or num <= minValues[-1]: minValues.append(num) print(i, sp, maxValues, minValues) while maxValues and minValues and i>sp and maxValues[-1] - minValues[-1] > limit: v = nums[sp] sp += 1 if v == maxValues[0]: del maxValues[0] if not maxValues: maxValues.append(max(nums[sp:i+1])) if v == minValues[0]: del minValues[0] if not minValues: minValues.append(min(nums[sp:i+1])) result = max(result, i-sp+1) return result