力扣-560. 和为 K 的子数组
参考自:https://leetcode-cn.com/problems/subarray-sum-equals-k/solution/he-wei-kde-zi-shu-zu-by-leetcode-solution/
class Solution1:
def subarraySum(self, nums, k):
res = 0
n = len(nums)
# 暴力解-相当于三重循环
for i in range(0, n):
for j in range(i + 1, n + 1):
if sum(nums[i:j]) == k:
res += 1
return res
class Solution2:
def subarraySum(self, nums, k):
res = 0
n = len(nums)
# 降低求和的计算复杂度
for i in range(0, n):
sum_ = 0
for j in range(i, n):
sum_ += nums[j]
if sum_ == k:
res += 1
return res
class Solution3:
def subarraySum(self, nums, k):
res = 0
n = len(nums)
# 记录前缀和--以空间换时间
dp = [0 for _ in range(n + 1)]
for i in range(1, n + 1):
dp[i] = sum(nums[:i])
for i in range(1, n + 1):
for j in range(i, n + 1):
if dp[j] - dp[i - 1] == k:
res += 1
return res
class Solution4:
def subarraySum(self, nums: List[int], k: int) -> int:
res = 0
n = len(nums)
# 记录前缀和--以空间换时间
# 使用哈希表记录前缀和,进一步优化时间复杂度
dp = {"0":1}
pre_sum = 0
count = 0
for i in range(0, n):
pre_sum += nums[i]
cur = str(pre_sum-k)
'''
关键点: 由dp[i] - dp[j] = k可得
dp[j] = dp[i] - k
因此只需要判断当前位置前的前序和中是否出现过dp[i] - k即可
--->dp[i:j]=k
'''
if cur in dp:
count += dp[cur]
dp[str(pre_sum)] = dp.get(str(pre_sum), 0) + 1
return count