链接: https://leetcode.cn/problems/binary-tree-paths/
题目描述:
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
![在这里插入图片描述](https://img-blog.csdnimg.cn/dd9990b0995e4e48a74e0f7d4fe9a461.png)
示例 1:
输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
示例 2:
输入:root = [1]
输出:["1"]
1.深搜写法1
用字符串path存储根节点到当前节点的路径,当搜到叶子节点,将结果保存至外部变量res。
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
def dfs(root, path):
if not root:
return
if not root.left and not root.right:
result.append(path + str(root.val))
path += str(root.val) + '->'
dfs(root.left, path)
dfs(root.right, path)
result = []
path = ''
dfs(root, path)
return result
2.深搜写法2
用数组path存储路径,手动回溯,避免创建新字符串的时间消耗。
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
def dfs(root, path, paths):
if not root:
return
if not root.left and not root.right:
paths.append('->'.join([str(node.val) for node in path]))
return
path.append(root.left)
dfs(root.left, path, paths)
path.pop() # 手动回溯
path.append(root.right)
dfs(root.right, path, paths)
path.pop()
path = [root]
paths = []
dfs(root, path, paths)
return paths
3.分治法
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
paths = self.devide_conquer(root)
return paths
def devide_conquer(self, root):
paths = []
if not root:
return paths
if not root.left and not root.right:
return [str(root.val)]
for path in self.devide_conquer(root.left):
paths.append(str(root.val) + '->' + path)
for path in self.devide_conquer(root.right):
paths.append(str(root.val) + '->' + path)
return paths
4变体:从根节点到叶节点的路径数字之和
- 从根节点到叶节点的路径数字之和https://leetcode.cn/problems/3Etpl5/
4.1 深搜dfs
这题就是在原来的基础上求所有路径值的总和,也可以先求出所有路径,再求和,但这样就有点浪费空间了,可以不保留路径,只保留根节点到当前节点的路径值,到达叶子节点再将最终路径值加到结果。
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
def dfs(root, pred_val, res):
if not root:
return
cur_val = pred_val * 10 + root.val
if not root.left and not root.right:
res[0] += cur_val
dfs(root.left, cur_val, res)
dfs(root.right, cur_val, res)
res = [0]
dfs(root, 0, res)
return res[0]
4.2 分治法
二叉树的题一般都可以使用分治法,这里将函数devide_conquer定义为从根节点到当前节点后,从当前节点到所有叶子节点的路径值之和,这样可以将问题转换为两个子问题:
devide_conquer(root) = devicd_conquer(root.left) + devide_conquer(root.right)
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
def devide_conquer(root, pre_val):
if not root:
return 0
cur_val = pre_val * 10 + root.val
if not root.left and not root.right:
return cur_val
return devide_conquer(root.left, cur_val) + \
devide_conquer(root.right, cur_val)
return devide_conquer(root, 0)