Leetcode 257. 二叉树的所有路径与变体


链接: https://leetcode.cn/problems/binary-tree-paths/
题目描述:
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
在这里插入图片描述
示例 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变体:从根节点到叶节点的路径数字之和

  1. 从根节点到叶节点的路径数字之和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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值