雖然以前在Sliding Window那篇小結裏總結了一些關於subarray sum的題目,但總以爲還不夠系統因此打算花更大的篇幅對leetcode中涉及到subarray sum的題目作一個小結。數組
1. 求subarray sum的最大值
53 Maximum Subarray:一道很是經典的dp題,這裏就不做總結了ide
2. 求知足條件的subarray sum的個數
560. Subarray Sum Equals K:
求subarray sum等於K的subarray的個數,這裏用HashMap記錄每一個前綴和的個數,和元素的正負無關。code
那若是不是要求相等,而是要求>=或<=K的個數呢(固然>或<也是同樣的,這裏僅用>=和<=作例子)?
(1)若是全部元素均爲正數:
印象中並未在leetcode中見過徹底同樣的題目,不過應該有一些相似的題目。總而言之都是用sliding window來處理,複雜度:O(N) O(1)。既然leetcode中沒找到,那就本身寫吧:
求一個正數數組中>=K的subarray sum的個數leetcode
public int countSubarray(int[] nums, int k) { for int count = 0, sum = 0, l = 0; for (int r = 0; r < nums.length; r ++) { sum += nums[r]; while (sum >= K) sum -= nums[l++]; count += l; } return count; }
求一個正數數組中<=K的subarray sum的個數get
public int countSubarray(int[] nums, int k) { int count = 0, sum = 0, l = 0; for (int r = 0; r < nums.length; r ++) { sum += nums[r]; while (sum > k) sum -= nums[l++]; count += r - l + 1; } return count; }
(2)若是去掉均爲正數的限制,數組中正負數都有可能出現
327. Count of Range Sum
和以前的題目相比,難度陡增,這道題merge sort/BIT/Segment Tree均可以解決,本質都是divide and conquer。複雜度:O(NlogN) O(1)我的更傾向於merge sort的解法(實際上是由於對BIT/Segment Tree用得不熟)hash
3.求知足條件的subarray sum的最短/最長lengthit
用hashmap記錄prefix sum和index的關係,index是該prefix sum首次出現的位置。若是題目改爲minimum size subarray sum equals k,那麼hashmap中就改爲記錄index最近出現的位置。這道題一樣和正負無關ast
非相等狀況:
(1)若是元素均爲正數
求一個正數數組中subarray sum >= k的最小長度test
求一個正數數組中subarray sum <= k的最大長度hashmap
public int maxLength(int[] nums, int k) { int sum = 0, max = 0, l = 0; for (int r = 0; r < nums.length; i ++) { sum += nums[r]; while (sum > k) sum -= nums[l++]; max = Math.max(r-l+1, max); } return max; }
(2) 若是元素可能存在負數
862. Shortest Subarray with Sum at Least K難度提升一個檔次,用sliding window + monotonic queue解決若是題目改爲shortest + at most k,longest + at least k, longest + at most k貌似都不可用上述方法解。