大家好,我是小卡皮巴拉
文章目录
目录
每篇前言
博客主页:小卡皮巴拉
咱的口号:🌹小比特,大梦想🌹
作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。
力扣题目:求根节点到叶节点数字之和
原题链接:129. 求根节点到叶节点数字之和 - 力扣(LeetCode)
题目描述
给你一个二叉树的根节点 root
,树中每个节点都存放有一个 0
到 9
之间的数字。
每条从根节点到叶节点的路径都代表一个数字:
- 例如,从根节点到叶节点的路径
1 -> 2 -> 3
表示数字123
。
计算从根节点到叶节点生成的 所有数字之和 。
叶节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3] 输出:25 解释: 从根到叶子节点路径1->2
代表数字12
从根到叶子节点路径1->3
代表数字13
因此,数字总和 = 12 + 13 =25
示例 2:
输入:root = [4,9,0,5,1] 输出:1026 解释: 从根到叶子节点路径4->9->5
代表数字 495 从根到叶子节点路径4->9->1
代表数字 491 从根到叶子节点路径4->0
代表数字 40 因此,数字总和 = 495 + 491 + 40 =1026
解题思路
问题理解
本题给定一个二叉树,树中每个节点存储一个 0 到 9 之间的数字。从根节点到叶节点的每条路径都可以表示一个数字(例如路径 1 -> 2 -> 3 表示数字 123)。要求计算所有从根节点到叶节点生成的数字之和。
算法选择
采用深度优先搜索(DFS)算法。通过递归地遍历二叉树的每一条从根到叶的路径,计算出每条路径所代表的数字,并将这些数字相加,从而得到最终的结果。
具体思路
-
主函数调用 DFS:在
sumNumbers
函数中,调用dfs
函数并传入根节点root
和初始的前缀和0
,开始深度优先搜索。 -
DFS 函数实现:
-
计算前缀和:在
dfs
函数中,将当前节点的值加入到前缀和presum
中,形成新的前缀和,即presum = presum * 10 + root->val
。 -
判断叶子节点:检查当前节点是否为叶子节点(即
root->left == nullptr && root->right == nullptr
)。如果是叶子节点,说明找到了一条从根到叶的路径,该路径代表的数字就是当前的前缀和,直接返回该值。 -
递归遍历子树:如果当前节点不是叶子节点,分别检查其左子节点和右子节点。如果有左子节点,递归调用
dfs
函数处理左子树,并将返回的结果累加到ret
中;如果有右子节点,同样递归调用dfs
函数处理右子树,并将结果累加到ret
中。 -
返回结果:遍历完所有子树后,
ret
中存储的就是从根到叶的所有路径代表的数字之和,返回ret
。
-
解题要点
-
前缀和的计算:正确理解并实现前缀和的计算方式,将路径上的数字依次拼接成一个完整的数字。
-
递归终止条件:准确判断叶子节点作为递归的终止条件,因为只有叶子节点才表示一条完整的从根到叶的路径。
-
递归调用:在递归过程中,正确处理左子树和右子树的递归调用,并将结果进行累加,以得到所有路径代表的数字之和。
完整代码(C++)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sumNumbers(TreeNode* root)
{
// 调用深度优先搜索函数 dfs 开始计算从根节点到叶节点生成的所有数字之和
// 初始的前缀和 presum 设为 0
return dfs(root, 0);
}
int dfs(TreeNode* root, int presum)
{
// 将当前节点的值加入到前缀和中,形成新的前缀和
// 因为路径上的数字是依次拼接的,所以当前前缀和要乘以 10 再加上当前节点的值
presum = presum * 10 + root->val;
// 判断当前节点是否为叶子节点(即没有左子节点和右子节点)
if(root->left == nullptr && root->right == nullptr)
// 如果是叶子节点,说明找到了一条从根到叶的路径,该路径代表的数字就是当前的前缀和,返回该值
return presum;
// 用于存储从根到叶的所有路径代表的数字之和
int ret = 0;
// 如果当前节点有左子节点,递归调用 dfs 处理左子树,并将结果累加到 ret 中
if(root->left) ret += dfs(root->left, presum);
// 如果当前节点有右子节点,递归调用 dfs 处理右子树,并将结果累加到 ret 中
if(root->right) ret += dfs(root->right, presum);
// 返回从根到叶的所有路径代表的数字之和
return ret;
}
};
兄弟们共勉 !!!
码字不易,求个三连
抱拳了兄弟们!