给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sum-equals-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:暴力枚举,三重循环
def subarraySum(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
nums_len, result = len(nums), 0
for i in range(nums_len):
for j in range(i, nums_len):
cur_sum = 0
for l in range(i, j + 1):
cur_sum += nums[l]
if cur_sum == k:
result += 1
return result
测试:
result = subarraySum([2, 3, 5, 8, 3], 5)
print(result)
解法二:
每次计算[i,len(nums)]
这个区间内以i
开始的每个小区间的和,记录所有和为k
的区间个数。通过遍历nums
每个元素i
,求解出每个以i
开始并且和为k
的区间个数,最后加在一起。
def subarraySum(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
nums_len, result = len(nums), 0
for i in range(nums_len):
print('i: ', i)
print('........................')
cur_sum = 0
for j in range(i, nums_len):
print('j: ', j)
print('{0} th sum: {1}'.format(j-1, cur_sum))
print('{0} th result: {1}'.format(j-1, result))
cur_sum += nums[j]
print('cur_sum of {0}: {1}'.format(j, cur_sum))
if cur_sum == k:
result += 1
print('sum = {0} at {1} th, cur result: {2}'.format(k, j, result))
print('--------------------')
print('#################################')
return result
测试:
result = subarraySum([2, 3, 5, 8, 3], 5)
print(result)
第三种解法:前缀和
令P[i] = A[0] + A[1] + ... + A[i-1]
,P[j] = A[0] + A[1] + ... + A[j-1]
,如果P[j] - P[i]= A[i] + A[i+1] + ... + A[j-1] == S
,那么[i,j]
就是我们需要的区间。对每个j
,计算有多少个i使得P[j] - P[i] == S
,这样就得到了以P[j]
作为右区间并且和为S
的区间数。对于A
中的每个元素都做同样的处理,最后将所有的结果相加。
通过hash_map
记录P[j]
。初始化时dict[0]=1
。因为当P[j]==S
时,P[i]=0
并且此时我们的result=1
。
def subarraySum(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
print('nums: ',nums)
print('======================================')
result, cur_sum = 0, 0
sum_dict = {0:1}
for num in nums:
print('num: ', num)
cur_sum += num
print('cur_sum: ', cur_sum)
print('cur_sum - k = ', cur_sum - k)
print('result:', result)
if cur_sum - k in sum_dict:
print('cur_sum - k = ', cur_sum - k)
result += sum_dict[cur_sum - k]
print('new result:', result)
print('Pre times of sum {0} is {1}'.format(cur_sum, sum_dict.get(cur_sum, 0)))
sum_dict[cur_sum] = sum_dict.get(cur_sum, 0) + 1
print('Modified times of sum {0} is {1}'.format(cur_sum, sum_dict.get(cur_sum, 0)))
print('New sum_dict: ', sum_dict)
print('..........................................')
return result
测试一:
result = subarraySum([2, 3, 5, 8, 3], 5)
print(result)
有一点需要注意,题目要求的是连续的子数组。
测试二:
result = subarraySum([2, 3, 5, 8, 3, 5], 5)
print(result)