【算法设计与分析】求根节点到叶节点数字之和

       📝个人主页:五敷有你      

 🔥系列专栏:算法分析与设计

⛺️稳中求进,晒太阳

题目

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

思路(递归)

        你可以使用深度优先搜索(DFS)来遍历树的所有路径。对于每个节点,你可以递归地计算从根节点到该节点的路径所代表的数字,并将其加到总和中。当遇到叶节点时,将路径所代表的数字加到总和中。

这里我们使用递归来解决这个问题。递归是一种解决问题的方法,其中函数调用自身来解决更小规模的问题。在树的情境下,递归特别适用,因为树的结构本身就是递归定义的。

递归函数的核心思路如下:

  1. 基本情况(终止条件)如果当前节点为空,则返回 0。
  2. 计算当前路径所代表的数字将当前路径的数字计算出来,即将当前的数字乘以 10 再加上当前节点的值。
  3. 处理叶子节点如果当前节点是叶子节点(即没有左右子节点),则返回当前路径所代表的数字。
  4. 递归左右子树对当前节点的左右子树分别调用递归函数,将当前路径所代表的数字传递给它们,并将它们返回的结果相加。
  5. 返回结果将左右子树返回的结果相加,得到从当前节点开始的所有路径所代表的数字之和。

我们就能够递归地计算出从根节点到每个叶子节点的路径所代表的数字之和。

代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumNumbers(TreeNode root) {
       return sum(root,0);
    }
    public int sum(TreeNode root,int i){
        if(root==null) return 0;
        int temp=i*10+root.val;
        if(root.left==null&&root.right==null){
            return temp;
        }
        return sum(root.left,temp)+sum(root.right,temp);
    }
}

运行结果

时间复杂度为 O(N),其中 N 表示树的节点数量。

  • 37
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
LeetCode解题总结 1. 数组 1.1 从有序数组中删除重复元素 1.2 在排序数组被旋转后进行查找 1.3 寻找两个排序数组的中位数 1.4 最长连续序列 1.5 累加和 1.6 移除数组中指定值 1.7 下一个排列 1.8 第n个全排列 1.9 验证数独的正确性 1.10 容纳雨水的量 1.11 旋转图像 1.12 数字加1 1.13 爬楼梯 1.14 格雷码 1.15 设置矩阵的行列为0 1.16 加油站问题 1.17 分糖果 1.18 只出现一次的数 2. 单链表 2.1 单链表相加 2.2 指定位置反转单链表 2.3 依据给定值将链表重新排序 2.4 删除链表中重复元素 2.5 指定位置旋转链表 2.6 删除倒数第N个节点 2.7 成对交换链表元素 2.8 复制复杂链表 2.9 链表环相关问题 2.9.1 链表是否有环 2.9.2 链表环的入口 2.10 改变链表中的元素位置2.11 LRU Cache(设计题) 3. 字符串 3.1 判断字符串是否为回文 3.2 实现strStr() 3.3 字符串转为int(atoi) 3.4 二进制树相加 3.5 最长回文字符串 3.6 正则表达式匹配[hard] 3.7 正则匹配 3.8 最长公共前缀 3.9 验证字符串是否为数字 3.10 数字转为罗马数字 3.11 罗马数字数字 3.12 Count and Say 3.13 变位词 3.14 简化系统路径 3.15 最后一个单词的长度 3.16 反转字符串中的单词 3.16.1 字符串前后和中间可能存在多个空格 3.16.2 不存在前后和中间的多余空格 3.17 一个编辑距离 4. 栈 4.1 验证括号的正确性 4.2 最长的正确括号表达式 4.3 柱状图中的最大矩形面积 4.4 计算逆波兰式的值 5. 树 5.1 二叉树的遍历 5.1.1 二叉树的前、中、后序遍历 5.1.2 二叉树的层序遍历 5.1.3 恢复二叉树[hard] 5.1.4 判断两棵树是否相等 5.1.5 判断二叉树是否为AVL树 5.1.6 将二叉树转为链表 5.1.7 二叉树添加指向右边节点的指针 5.1.8 树中节点的最小公共祖先 5.2 二叉树的构建5.3 二叉查找树 5.3.1 生成不重复的二叉查找树数目 5.3.2 验证是否为二叉查找树 5.3.3 将有序数组转为二叉树 5.3.4 将有序链表转为二叉树 5.4 二叉树的递归 5.4.1 二叉树的最大深度 5.4.2 二叉树的最小深度 5.4.3 路径和 5.4.4 满二叉树添加指向右边节点的指针 5.4.5 根节点结点的所有路径代表的数字之和 6. 排序 6.1 合并两个有序数组到其中一个数组 6.2 合并两个有序链表 6.3 合并K个有序链表 6.4 使用插入排序来排序链表 6.5 归并排序排序链表 6.6 第一个缺少的正数 6.7 排序颜色 7. 查找 7.1 在排序数组中查找数出现的范围 7.2 在排序数组中查找给定值的插入位置 7.3 在二维排序数组中查找给定值 7.4 在旋转有序数组中查找最小值 7.4.1 数组无重复 7.4.2 数组有重复 7.5 在旋转排序数组中查找指定数字 8. 暴力枚举法 8.1 求集合的子集 8.2 集合的全排列 8.3 在指定树中选择进行全排列 8.4 电话上对应数字的字母组成的所有单词 9. 广度优先搜索 9.1 单词变换路径(Word Ladder) 9.1.1 是否存在变换路径 9.1.2 所有最短变换路径9.2 包围区域 10. 深度优先搜索 10.1 N皇后问题 10.2 恢复IP地址 10.3 集合元素之和 10.3.1 元素可以重复 10.3.2 元素不可重复 10.3.3 给定元素数目和元素范围 10.4 正确的括号对 10.5 解数独 10.6 单词搜索 10.7 小结 10.7.1 适用场景 10.7.2 思考步骤 10.7.3 代码模板 10.7.4 深搜与回溯、递归的区别 11. 分治法 11.1 实现pow(x, n) 11.2 Sqrt(x) 12. 贪心算法 12.1 跳台阶游戏 12.2 买卖股票的最佳时机 12.2.1 最多允许交易一次 12.2.2 可以交易任意多次 12.2.3 最多可以交易两次 12.2.4 可以交易任意多次 12.2.5 交易后需要停止一段时间 12.3 最长不含重复元素的子串 12.4 存放的最大水量 13. 动态规划 13.1 三角形从顶到底的最小路径和 13.2 最大连续子数组 13.3 字符串的所有子回文字符串 13.4 最长公共子序列问题 13.5 字符串的编辑距离 13.6 不同路径之和 13.6.1 无障碍13.6.2 有障碍 13.7 最大矩形面积 13.8 字符串交叉组合 13.9 旋转字符串 13.10 最小路径和 13.11 所有的编码方式 13.12 独一无二的子序列数 13.13 拆分单词 13.13.1 单词是否由词典中的单词组成 13.13.2 返回所有可以切分的解 14. 图 14.1 图的克隆 15. 细节实现题 15.1 反转整数 15.2 对称数判断 15.3 区间的相关操作 15.3.1 在区间中插入新的区间 15.3.2 合并区间 15.4 包含子串元素的最小窗口 15.5 大数乘法 15.6 给定串中是否存在包含所有单词的子串 15.7 Pascal 三角形 15.7.1 生成Pascal三角形 15.7.2 Pascal三角形的第N行 15.8 螺旋形矩阵 15.8.1 螺旋打印矩阵 15.8.2 生成螺旋矩阵 15.9 Z字形输出字符串 15.10 不使用乘、除、取模实现两个整数相除 15.11 文本对齐 15.12 共线的最大点数 16 其他问题 16.1 随机数生成器
村里有唯一一个泥瓦匠叫Kemo,很多人需要找Kemo修房子、修灶台、造花园……等,大家可以向Kemo预约修葺的时间和工钱。 现在情况是: 1)Kemo只有一个人,不能同时为两个雇主工作 2)Kemo只有干完一个雇主家的活才可以在接下来的一天切换到另一个雇主家里干活。未干完一份活不可以离开,不可以为多位雇主交叉时间干活 3)Kemo如果不能在预约的时间那天应约的话,这个雇主的这份钱就挣不到了 Kemo比较聪明,他把大家的预约收集好,想让自己忙碌一阵子,赚最多的钱。现在请你为这个忙碌而又贪心的Kemo设计一个思路吧。 Input 输入4行: 第一行,一个数字,n,表示n个人向Kemo预约需要修葺(n<=100) 第二行,n个正数,表示这n个人所需完成修葺的时间的起始点。若时间点为8,表示第8天开始 第三行,n个正数,表示这n个人所需完成修葺的工程天数。若天数为3,表示这一工程必须维持3天完成(所有工程都可以在第1000天内完成,即起始点+工期<=1000) 第四行,n个正数,表示这n个人能向Kemo付出的工钱,工钱以每天计 Output 输出:忙完这阵子,Kemo最多能挣多少钱? 例如:4个人需要找Kemo修葺,起始时间、工期和每天的工钱分别是: 1 3 8 4 3 2 3 2 5 6 10 7 则:Kemo可以获得的最大收益为:5*3+10*3+7*2 = 59 Sample Input 4 1 3 8 4 3 2 3 2 5 6 10 7 Sample Output 59 Hint 此题标题虽有“贪心”,但勿掉入贪心的陷阱中哦(贪心法是解不了滴)。 每项工程有“起始时间”,“工期”和“工钱数”三个性质。若两个工程的从起始时间到结束都不相冲突,就定义这两个工程为“相容工程”。 做子集树,根结点为第1层,节点为n+1层。子集树的第i层结点的两个分支代表第i个工程选或者不选。 用回溯算法搜索这n+1层的完全二叉树。 1)若当前工程和之前已选的工程集合不相容,则剪去该分支,不进行该分支之下的搜索,返回到上层结点。 2)将所有满足相容性的可行的节点,计算获得的最大工钱数。
数据结构:⼋⼤数据结构分析 数据结构分类 数据结构是指相互之间存在着⼀种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 常⽤的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所⽰: 线性表和⾮线性表 ⼀、线性表 常见的线性表有:数组、队列、栈、链表 线性表是最基本、最简单、也是最常⽤的⼀种数据结构。线性表(linear list)是数据结构的⼀种,线性表就是数据排列成⼀条先⼀样的结 构,每个线性表上的数据最多只有前和后两个⽅向。⼀个线性表是n个具有相同特性的数据元素的有限序列。 特点: 1. 集合中必存在唯⼀的⼀个"第⼀元素"。 2. 集合中必存在唯⼀的⼀个 "最后元素" 。 3. 除最后⼀个元素之外,均有唯⼀的后继(后件)。 4. 除第⼀个元素之外,均有唯⼀的前驱(前件)。 顺序表⾥⾯元素的地址是连续的;链表⾥⾯节点的地址不是连续的,是通过指针连起来的。 1.数组 数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进⾏访问,数组下标从0开始。例 如下⾯这段代码就是将数组的第⼀个元素赋值为 1。 int[] data = new int[100];data[0] = 1; 优点: 1、按照索引查询元素速度快 2、按照索引遍历数组⽅便 缺点: 1、数组的⼤⼩固定后就⽆法扩容了 2、数组只能存储⼀种类型的数据 3、添加,删除的操作慢,因为要移动其他的元素。 适⽤场景: 频繁查询,对存储空间要求不⼤,很少增加和删除的情况。 2.栈 栈是⼀种特殊的线性表,仅能在线性表的⼀端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出,从栈 顶放⼊元素的操作叫⼊栈,取出元素叫出栈。 栈的结构就像⼀个集装箱,越先放进去的东西越晚才能拿出来,所以,栈常应⽤于实现递归功能⽅⾯的场景,例如斐波那契数列。 3.队列 队列与栈⼀样,也是⼀种线性表,不同的是,队列可以在⼀端添加元素,在另⼀端取出元素,也就是:先进先出。从⼀端放⼊元素的操作称 为⼊队,取出元素为出队,⽰例图如下: 使⽤场景:因为队列先进先出的特点,在多线程阻塞队列管理中⾮常适 ⽤。 4.链表 链表是物理存储单元上⾮连续的、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,⼀个是存 储元素的数据域 (内存空间),另⼀个是指向下⼀个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表, 循环链表等。 链表的优点: 1. 链表是很常⽤的⼀种数据结构,不需要初始化容量,可以任意加减元素; 2. 添加或者删除元素时只需要改变前后两个元素结点的指针域指向地址即可,所以添加,删除很快; 缺点: 1. 因为含有⼤量的指针域,占⽤空间较⼤; 2. 查找元素需要遍历链表来查找,⾮常耗时。 适⽤场景: 数据量较⼩,需要频繁增加,删除操作的场景 ⼆、⾮线性表 常见的⾮线性表有:树、图、堆 ⾮线性表中数据并不是简单的前后关系。 1.树 树是⼀种数据结构,它是由n(n>=1)个有限节点组成⼀个具有层次关系的集合。把它叫做 "树" 是因为它看起来像⼀棵倒挂的树,也就 是说它是根朝上,⽽朝下的。它具有以下的特点: 每个节点有零个或多个⼦节点; 没有⽗节点节点称为根节点; 每⼀个⾮根节点有且只有⼀个⽗节点; 除了根节点外,每个⼦节点可以分为多个不相交的⼦树; 在⽇常的应⽤中,我们讨论和⽤的更多的是树的其中⼀种结构,就是⼆叉树。 ⼆叉树是树的特殊⼀种,具有如下特点: 每个结点最多有两颗⼦树,结点的度最⼤为2。 左⼦树和右⼦树是有顺序的,次序不能颠倒。 即使某结点只有⼀个⼦树,也要区分左右⼦树。 ⼆叉树是⼀种⽐较有⽤的折中⽅案,它添加,删除元素都很快,并且在查找⽅⾯也有很多的算法优化,所以,⼆叉树既有链表的好处,也有 数组的好处,是两者的优化⽅案,在处理⼤批量的动态数据⽅⾯⾮常有⽤。 2.散列表 散列表,也叫哈希表,是根据关键码和值 (key和value) 直接进⾏访问的数据结构,通过key和value来映射到集合中的⼀个位置,这样就可 以很快找到集合中的对应元素。 记录的存储位置=f(key) 这⾥的对应关系 f 成为散列函数,⼜称为哈希 (hash函数),⽽散列表就是把Key通过哈希函数转换成⼀个整型数字,然后就将该数字对数 组长度进⾏取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间⾥,这块连续存储空间称为散列表或哈希表 (Hash table),这种存储空间可以充分利⽤数组的查找优势来查找元素,所以查找的速度很快。 散列数据结构的性能取决于以下三个因素: 哈希函数 哈希表的⼤⼩ 碰撞处理⽅法 哈希表在应⽤中也是⽐较常见的,就如Java中有些集合类

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五敷有你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值