记录在做hot100时遇到的前缀和的题目。
目前见过的题目,都是前缀和结合其它的方法一起使用:用于求取一段连续路径的和(最大值/最小值/目标出现次数)。
需要注意的是,前缀和的判定方法是node2.val-node1.val == target,不要搞错顺序。
文章目录
- 1.路径之和III
- 2.和为 K 的子数组
1.路径之和III
在数据结构 - 二叉树记录过,此处单独拿出来。
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
符合求取连续路径的和的特点。
使用DFS+前缀和的思路。DFS的一个明显好处是,每条正在搜索的路径一定符合题目中对路径的要求。将当前路径节点的前缀和记录到path(此处为memo)备用。
class Solution(object):res = 0def pathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: int"""self.res = 0path = [0] # 记录当前路径的前缀和def dfs(node, targetSum):# 出口if node is None:return False# 一般情况path.append(node.val + path[-1])for i in range(len(path) - 1):if path[-1] - path[i] == targetSum:self.res += 1# 执行选择并撤销if dfs(node.left, targetSum):path.pop()if dfs(node.right, targetSum):path.pop()return Truedfs(root, targetSum)return self.res
---------------------------------这样也是可以的,dfs路径选择和退出的位置要对应-----------------------------------class Solution(object):res = 0def pathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: int"""self.res = 0path = [0] # 记录当前路径的前缀和def dfs(node, targetSum):# 出口if node is None:return# 一般情况path.append(node.val + path[-1]) # 在这选择for i in range(len(path) - 1):if path[-1] - path[i] == targetSum:self.res += 1dfs(node.left, targetSum)dfs(node.right, targetSum) path.pop() # 在这退出dfs(root, targetSum)return self.res
2.和为 K 的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回该数组中和为 k 的连续子数组的个数
符合求取连续路径的和
class Solution(object):def subarraySum(self, nums, k):""":type nums: List[int]:type k: int:rtype: int"""# 前缀和+哈希表# 对于数组/树 的连续路径上求和,可以用前缀和相减record = dict() # 前缀和key 出现次数为valrecord[0] = 1 # 为了能计算首个元素summary = 0res = 0for num in nums:summary += num# 查看之前是否有结果if record.__contains__(summary - k): # !!!!!!!!!!!!!!!!!res += record[summary - k]# 更新recordif record.__contains__(summary):record[summary] += 1else:record[summary] = 1return res
- 这里如果需要获得具体的序列,也可以使用滑动窗口解决
class Solution:def FindContinuousSequence(self, tsum):if tsum <= 1:return []start, end = 0, 1summary = 0res = [] while (start <= end and end <= (tsum // 2 + 2)):if summary == tsum:res.append([i for i in range(max(start, 1), end)])summary += end end += 1elif summary < tsum:summary += end end += 1else:summary -= start start += 1return res