【LeetCode】560. 和为 K 的子数组
原创
©著作权归作者所有:来自51CTO博客作者说文科技的原创作品,请联系作者获取转载授权,否则将追究法律责任
0.总结
- 子数组和子序列是两个完全不同的概念
- 本题的主要思想是前缀和+映射表的使用
- 博客来源:LawsonAbs@CSDN
1.题目
2.思想
3.代码
from copy import copy
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
prefix_sum = [0] * (len(nums)+1)
sum_cnt = {0:1}
res = 0
for i in range(len(nums)):
prefix_sum[i+1] = prefix_sum[i] + nums[i]
res += sum_cnt.get(prefix_sum[i+1]-k,0)
sum_cnt[prefix_sum[i+1]] = sum_cnt.get(prefix_sum[i+1],0) + 1
return res
4.
如果将子数组改成子序列,那么思想就是采用深搜 的方法,
- step1 先对数组进行排序
- step2.如何控制重复? -> 从左往右遍历的时候添加一个起始位置,同时判断当前这个数和下一个数是否相等,如果相等,则继续下移
得到的代码就如下:
from copy import copy
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
nums.sort()
vis = [0]*len(nums)
total = 0
res = []
cur = []
for start in range(len(nums)):
if start>=1 and nums[start] == nums[start-1]:
continue
vis[start] = 1
cur.append(nums[start])
self.dfs(start,nums[start]+total,k,res,vis,nums,cur)
vis[start] = 0
cur.pop()
print(res)
return len(res)
def dfs(self,start,total,k,res,vis,nums,cur):
if total == k:
res.append(copy(cur))
return
for i in range(start+1,len(nums)):
if vis[i] == 0:
if nums[i] + total > k:
break
vis[i] = 1
cur.append(nums[i])
self.dfs(i,nums[i]+total,k,res,vis,nums,cur)
vis[i] = 0
cur.pop()
只不过,这里的复杂度,可能