虽然以前在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貌似都不可用上述方法解。