![81e3fc2666b87e12880a7434fdd17d09.png](https://i-blog.csdnimg.cn/blog_migrate/e305ed549d38b0a9d935689c27618ce0.jpeg)
快乐总是短暂的,换来的却是无穷无尽的痛苦和长叹。《大话西游》
轻车熟路的每日一题
路径总和leetcode-cn.com给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明:
叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/
4 8
/ /
11 13 4
/
7 2 1
这里直接是求根节点到叶节点的总和,也不用求中间连续的节点值之和。这里直接按照递归的思想,一直递归到叶子节点,如果到都不满足,还会往下递归到空直接返回False就行了。如果满足这时候正好满足等于叶子节点的值,既然是叶子节点同时也要满足左右子节点为空。
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return False
if sum == root.val and not root.left and not root.right:
return True
return self.hasPathSum(root.left, sum-root.val) or self.hasPathSum(root.right, sum-root.val)
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明:
叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/
4 8
/ /
11 13 4
/ /
7 2 5 1
这里依旧是求这样的路径,但是这里是列举出所有可能。为了对每一种可能记录入最后的答案,因此还需要一个临时列表进行存储,使用深度优先遍历。只要满足左右节点为空并且sum为root的值则把这个列表添加进答案列表里。
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
ans = []
def dfs(root, temp, sum):
nonlocal ans
if not root:
return
if not root.left and not root.right and sum == root.val:
ans.append(temp + [root.val])
dfs(root.left, temp + [root.val], sum - root.val)
dfs(root.right, temp + [root.val], sum - root.val)
return ans
dfs(root, [], sum)
return ans
给定一个二叉树,它的每个结点都存放着一个整数值。找出路径和等于给定数值的路径总数。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。
示例:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/
5 -3
/
3 2 11
/
3 -2 1
#返回3
这里的问题是不需要记录路径只用记录路径数,但是可以不从根节点开始。可以看成是对每一个节点进行深度有限搜索,只要从这个节点开始满足条件,就将计数加1 。
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
if not root:
return 0
return self.dfs(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum)
def dfs(self, root, path):
if not root:
return 0
path -= root.val
return (1 if path==0 else 0) + self.dfs(root.left, path) + self.dfs(root.right, path)
看了评论后发现也有另外的解法,不需要两个递归;其实一般来说有时候一个递归都有些难解。为了将两个递归简化为一个递归,因此需要一个中间的步骤。即在中间多进行一个迭代操作,每次将从根节点到叶节点内的所有路径都记录下来,然后判断这个链表里有多少个满足条件。
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
def dfs(root, sumlist):
if root is None:
return 0
sumlist = [num+root.val for num in sumlist]
sumlist.append(root.val)
count = 0
for num in sumlist:
if num == sum:
count += 1
return count + dfs(root.left, sumlist) + dfs(root.right, sumlist)
return dfs(root, [])
示例:
#nums = [1, 2, 3]
#target = 4
#所有可能的组合:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
#请注意,顺序不同的序列被视作不同的组合。
#因此输出为 7。
这里看着其实非常像之前的兑换零钱2,但是又有一点区别就是它有顺序,只要顺序不同就是一个新方法;这在兑换零钱里是不需要考虑的,只用考虑用了哪一种。为了不让重复的消失掉,因此将循环的顺序进行了调换;也就是当target值为4的时候的所有可能,不管重复不重复。
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
if not nums:
return 0
dp = [0] * (target+1)
dp[0] = 1
for i in range(target+1):
for n in nums:
if (i+n) <= target:
dp[i+n] = dp[i+n] + dp[i]
return dp[-1]
参考博客:
力扣
路径总和3
关于python的self