题目
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入: nums = [1, 1, 1], k = 2
输出: 2, [1, 1] 与 [1, 1] 为两种不同的情况。
说明 :**
- 数组的长度为
[1, 20,000]。 数组中元素的范围是
[-1000, 1000],且整数 k 的范围是[-1e7, 1e7]。方案一(暴力法)
class Solution:def subarraySum(self, nums: List[int], k: int) -> int:# 暴力法count = 0for i in range(len(nums)):for j in range(i, len(nums)):if sum(nums[i:j+1]) == k:count += 1return count
-
方案二(使用哈希表优化)
class Solution:def subarraySum(self, nums: List[int], k: int) -> int:# 假如存在区间[left,right],使得在[left,right]这个区间的子数组的和为k。换句话说,就是前right项和减去前left项和等于k,即前left项和等于前right项和减去k。# 可以这样做,在扫描数组的同时,假设当前扫到第i位,记录它的前i项和sum,用该和减去k,即sum-k,判断sum-k是否为某个位置的前n项和,若是,更新统计量。count, ans = 0, 0pre = collections.defaultdict(int)pre[0] += 1 # 初始化时,前缀和为 0 出现过 1 次(空的时候)for num in nums:count += numif count - k in pre:ans += pre[count - k]pre[count] += 1return ans
方法三(动态规划思想)
class Solution:def subarraySum(self, nums: List[int], k: int) -> int:# 动态规划# dp[i] 表示 nums[:i] 之内和为 k 的连续子数组的个数dp = [0]for index, num in enumerate(nums):# 包含当前 num 且和为 k 的连续子数组的个数count, amount = 0, 0 # 连续子数组的和,以及和为 k 的数量for j in range(index, -1, -1):count += nums[j]if count == k:amount += 1dp.append(dp[-1] + amount)return dp[-1]
-
原文
https://leetcode-cn.com/explore/interview/card/2020-top-interview-questions/284/hash-map/1272/
https://leetcode-cn.com/problems/subarray-sum-equals-k/solution/he-wei-kde-zi-shu-zu-by-leetcode-solution/
https://leetcode-cn.com/problems/subarray-sum-equals-k/solution/qian-zhui-he-shi-xian-jian-dan-by-jarvis1890/
