LeetCode刷题--- 求根节点到叶节点数字之和

2023-12-09 19:20

本文主要是介绍LeetCode刷题--- 求根节点到叶节点数字之和,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客

个人专栏:http://t.csdnimg.cn/ZxuNL

                 http://t.csdnimg.cn/c9twt


前言:这个专栏主要讲述递归递归、搜索与回溯算法,所以下面题目主要也是这些算法做的  

我讲述题目会把讲解部分分为3个部分:
1、题目解析

2、算法原理思路讲解

3、代码实现


一、求根节点到叶节点数字之和

题目链接: 求根节点到叶节点数字之和

题目:

给你一个二叉树的根节点 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

提示:

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

二、解法  

题目解析

这道题目的意思是:给我们一棵二叉树,让我们计算从根节点到叶节点生成的 所有数字之和 。

例如:

示例 :

从根到叶子节点路径 4->9->5                代表数字 495
从根到叶子节点路径 4->9->1                代表数字 491
从根到叶子节点路径 4->0                   代表数字 40
因此,数字总和 = 495 + 491 + 40 = 1026

  算法原理思路讲解 

注意:我们在做递归这一类题目是要将递归看作一个黑盒,我们不管他是如何实现的,我们就相信他一定可以帮助我们完成目标

递归思路:
1、设计函数头(寻找重复子问题,并且将递归函数看作一个黑盒)。

2、设计函数体(只关心一个子问题,并解决它)

3、设计函数出口(递归的终止条件)


算法思路:

根据题目意思可得,我们可以使用一个前序遍历

在前序遍历的过程中,我们可以往左右⼦树传递信息,并且在回溯时得到左右⼦树的返回值。递归函数可以帮我们完成两件事:

1.、将⽗节点的数字与当前节点的信息整合到⼀起,计算出当前节点的数字,然后传递到下⼀层进⾏递归
2、当遇到叶⼦节点的时候,就不再向下传递信息,⽽是将整合的结果向上⼀直回溯到根节点。
在递归结束时,根节点需要返回的值也就被更新为了整棵树的数字和。

把上面翻译一下就是 

例如对于节点9来说

1、节点9将⽗节点的数字(4)与自己的数字9结合在一起成49传递到下一层

2、当遇到节点5的时候,就不再向下传递信息,⽽是将整合的结果(495)返回

  1、设计函数头

int dfs(TreeNode* root, int num)

(1) 返回值:当前⼦树计算的结果(数字和) 

(2)参数 num:递归过程中往下传递的信息(⽗节点的数字)

(3) 函数作⽤:整合⽗节点的信息与当前节点的信息计算当前节点数字,并向下传递,在回溯时返回当前⼦树(当前节点作为⼦树根节点)数字和。

2、设计函数体(只关心一个子问题,并解决它)

  • 当遇到空节点的时候,说明这条路从根节点开始没有分⽀,返回 0;
  • 结合⽗节点传下的信息以及当前节点的 val,计算出当前节点数字 presum;
  • 如果当前结点不是叶⼦节点,将 presum 传到左右⼦树中去,得到左右⼦树中节点路径的数字和,然后相加后返回结果。
presum = presum * 10 + root->val;int ret = 0;
if(root->left) ret += dfs(root->left, presum);
if(root->right) ret += dfs(root->right, presum);
return ret;

3、设计函数出口

 如果当前结点是叶⼦节点,直接返回整合后的结果 presum

if(root->left == nullptr && root->right == nullptr)return presum;

以上思路就讲解完了,大家可以先自己先做一下


  • 时间复杂度:O(n),其中 n 是二叉树的节点个数。对每个节点访问一次。
  • 空间复杂度:O(n),其中 n 是二叉树的节点个数。空间复杂度主要取决于递归调用的栈空间,递归栈的深度等于二叉树的高度,最坏情况下,二叉树的高度等于节点个数,空间复杂度为 O(n)。

代码实现

/*** 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 dfs(TreeNode* root, int presum){presum = presum * 10 + root->val;if(root->left == nullptr && root->right == nullptr)return presum;int ret = 0;if(root->left) ret += dfs(root->left, presum);if(root->right) ret += dfs(root->right, presum);return ret;}int sumNumbers(TreeNode* root) {return dfs(root,0);}
};

这篇关于LeetCode刷题--- 求根节点到叶节点数字之和的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/474804

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return