Skip to content

M129.求根节点到叶节点数字之和

dfs, https://leetcode.cn/problems/sum-root-to-leaf-numbers/

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 09 之间的数字。

每条从根节点到叶节点的路径都代表一个数字:

  • 例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123

计算从根节点到叶节点生成的 所有数字之和

叶节点 是指没有子节点的节点。

示例 1:

img
输入:root = [1,2,3]
输出:25
解释:
从根到叶子节点路径 1->2 代表数字 12
从根到叶子节点路径 1->3 代表数字 13
因此,数字总和 = 12 + 13 = 25

示例 2:

img
输入:root = [4,9,0,5,1]
输出:1026
解释:
从根到叶子节点路径 4->9->5 代表数字 495
从根到叶子节点路径 4->9->1 代表数字 491
从根到叶子节点路径 4->0 代表数字 40
因此,数字总和 = 495 + 491 + 40 = 1026

提示:

  • 树中节点的数目在范围 [1, 1000]
  • 0 <= Node.val <= 9
  • 树的深度不超过 10

思路:用栈模拟递归。

python
class Solution:
    def sumNumbers(self, root: Optional[TreeNode]) -> int:
        stack = [(root, 0)]
        ans = 0

        while stack:
            node, cur = stack.pop()
            cur = cur * 10 + node.val
            if node.left is None and node.right is None:
                ans += cur
            if node.left is not None:
                stack.append((node.left, cur))
            if node.right is not None:
                stack.append((node.right, cur))

        return ans

有多少个叶子结点就有多少次加和,因此递归的本质就是不断逼近叶子结点。

思路:

  • 如果此节点是叶节点,则返回现在的总和
  • 递归,如果当前节点不是叶节点,就把当前总和设为左子树根节点和右子树根节点的current_sum的和

思路: 由路径组成的数字要想到每往前一位就相当于×10再相加,在此基础上进行递归。

  1. 深度优先搜索 (DFS)
    • 使用递归方法从根节点开始向下遍历。
    • 在每一步中,将当前路径上的数字更新为 current_number = current_number * 10 + node.val
    • 如果到达叶节点(即没有左子节点和右子节点),将当前路径的数字加入结果总和。
  2. 递归终止条件
    • 当前节点为空时,直接返回。
    • 当前节点是叶节点时,将当前路径的数字加入总和。
  3. 时间复杂度
    • 每个节点访问一次,时间复杂度为 O(n),其中 n 是节点总数。
  4. 空间复杂度
    • 递归调用栈的空间复杂度为 O(h),其中 h 是树的高度。
python
# 定义二叉树节点类
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

from typing import Optional

class Solution:
    def sumNumbers(self, root: Optional[TreeNode]) -> int:
        """
        计算从根节点到叶节点生成的所有数字之和。
        :param root: Optional[TreeNode], 二叉树的根节点
        :return: int, 所有路径数字的总和
        """
        def dfs(node, current_number):
            if not node:
                return 0
            
            # 更新当前路径的数字
            current_number = current_number * 10 + node.val
            
            # 如果是叶节点,返回当前路径的数字
            if not node.left and not node.right:
                return current_number
            
            # 递归处理左右子树
            left_sum = dfs(node.left, current_number)
            right_sum = dfs(node.right, current_number)
            
            # 返回左右子树的结果之和
            return left_sum + right_sum
        
        # 从根节点开始递归
        return dfs(root, 0)

# 测试代码
if __name__ == "__main__":
    # 示例 1: 构建树 [1,2,3]
    root1 = TreeNode(1)
    root1.left = TreeNode(2)
    root1.right = TreeNode(3)
    solution = Solution()
    print(solution.sumNumbers(root1))  # 输出: 25

    # 示例 2: 构建树 [4,9,0,5,1]
    root2 = TreeNode(4)
    root2.left = TreeNode(9)
    root2.right = TreeNode(0)
    root2.left.left = TreeNode(5)
    root2.left.right = TreeNode(1)
    print(solution.sumNumbers(root2))  # 输出: 1026

黄一田 物理学院:将各点连接成的字符串加入递归变量中就不难处理了,找叶子结点也是很模板化的处理。

python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumNumbers(self, root: Optional[TreeNode]) -> int:
        def s(node,string):
            if node==None:
                return 0
            if node.left==node.right==None:
                return int(string+str(node.val))
            return s(node.left,string+str(node.val))+\
            s(node.right,string+str(node.val))
        return s(root,'') if root else 0