【LeetCode】剑指 Offer 34. 二叉树中和为某一值的路径 p182 -- Java Version
创始人
2025-06-01 11:03:06
0

题目链接:https://leetcode.cn/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/

1. 题目介绍(34. 二叉树中和为某一值的路径)

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
……
叶子节点 是指没有子节点的节点。

【测试用例】:
示例 1:
在这里插入图片描述

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:
在这里插入图片描述

输入:root = [1,2,3], targetSum = 5
输出:[]

示例3:

输入:root = [1,2], targetSum = 0
输出:[]

【条件约束】:

提示

  • 树中节点总数在范围 [0, 5000] 内
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000

【相关题目】:

注意:本题与主站 113. 路径总和 II 题目相同。

2. 题解

在这里插入图片描述

2.1 递归(原书题解)-- O(n2)

时间复杂度O(n2),空间复杂度O(n)

【解题思路】

  1. 使用前序遍历来遍历二叉树,当通过前序遍历的方式访问到某一个节点时,我们把该节点添加到路径上,并累加该节点的值
  2. 如果该节点为叶节点,并且路径中节点值的和刚好等于输入的整数,则当前路径符合要求,我们把它打印出来。
  3. 如果当前节点不是叶节点,则继续访问它的子节点。
  4. 当前节点访问结束后,递归方法将自动回到它的父节点。因此,我们在方法退出之前要在路径上删除当前节点并减去当前节点的值,以确保返回父节点时路径刚好是从根节点到父节点。
    ……

我们不难看出保存路径的数据结构实际上是一个栈,因为路径要与递归调用状态一致,而递归调用的本质就是一个压栈和出栈的过程。
……
【注意点】

  1. Stack的泛型直接定义为 Integer 即可,如果定义成 TreeNode ,为了返回结果,反而会需要额外定义List来存储单个路径。
  2. 递归结束条件,一般情况下,递归需要由一个终止条件才行。但是下面解法中的递归会自动执行完毕,即遍历完所有节点,栈内元素会全部弹出完毕,执行终止,不存在无限循环的情况。
  3. 将Stack类型转换为List类型List list = new LinkedList<>(stack);
    更多内容可参考:【Java】stack转为list
/*** 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 {// 解题思路:// 路径:由根节点到叶子节点所经过的所有节点共同组成// 叶子节点:是指没有子节点的节点// 定义返回列表List> list;public List> pathSum(TreeNode root, int targetSum) {// 判空if (root == null) return new ArrayList<>();// 定义栈来存储路径Stack path = new Stack<>();// 返回列表初始化list = new ArrayList<>();// 进入递归findPath(root, targetSum, path, 0);// 递归结束,返回结果return list;}public void findPath(TreeNode root, int targetSum, Stack path, int currSum){// 压入栈后,增加当前路径和currSum += root.val;// 从根节点出发,将根节点存入栈内path.push(root.val);// 递归结束条件,路径和符合条件,记录该路径// 1. 判断当前节点是否为叶子节点boolean isLeaf = (root.left == null) && (root.right == null);// 2. 路径和符合条件if ((currSum == targetSum) && isLeaf) {List row = new ArrayList<>(path);list.add(row);}// 遍历其子节点if (root.left != null) findPath(root.left, targetSum, path, currSum);if (root.right != null) findPath(root.right, targetSum, path, currSum);// 弹出节点path.pop();}
}

代码简化:

简化内容

  1. 递归函数的设计更加简洁,相较于原书题解中的四个参数,这里仅保留了用户需要输入的两个参数;
  2. 确定符合条件的路径方法也更简洁,原书题解中是通过自己新定义的变量 currSum 根据遍历进行累加计算,直至等于 targetSum;而简化题解中,反其道而行之,直接对 targetSum 进行修改,直至其减到0,认为当前路径符合条件,可以保留;
  3. 左、右子节点的递归没有设置判断条件,而是设置了递归结束条件 root == null (意为,当前节点为空时,结束当前递归)。
    ……

优化内容

  1. Stack换成了Deque,在力扣提交中提升了 1s 的效率:
    在这里插入图片描述
    其原因在于:Stack 基于数组实现,LinkedList基于链表实现 (Deque是基于LinkedList实现的),数组随机访问效率高,但随机插入、随机删除效率低,链表与之相反。那么对于这道题,有频繁的插入、删除操作,那么我们利用LinkedList实现栈自然比Stack快很多了。
    ……
    更多内容可参考
    [1] LeetCode刷题心得记录——为什么LinkedList比Stack效率要高?
    [2] JAVA 栈,为什么要使用Deque,而不推荐使用Stack
    [3] Java中的栈Stack、Deque、ArrayDeque、LinkedList
    [4] Java 容器源码分析之 Deque 与 ArrayDeque
class Solution {List> ret = new LinkedList>();// 优化:在这里LinkedList 要比 Stack 效率要高Deque path = new LinkedList();public List> pathSum(TreeNode root, int targetSum) {dfs(root, targetSum);return ret;}// 深度优先遍历// 简化1:设计的递归函数更加简洁,仅使用了两个参数public void dfs(TreeNode root, int targetSum) {if (root == null) {return;}path.offerLast(root.val);// 简化2:修改targetSum的值,减至0时,认为路径符合条件targetSum -= root.val;if (root.left == null && root.right == null && targetSum == 0) {ret.add(new LinkedList(path));}// 左子节点dfs(root.left, targetSum);// 右子节点dfs(root.right, targetSum);// 弹出/删除路径path.pollLast();}
}

2.2 广度优先搜索 – O(n2)

时间复杂度O(n2),空间复杂度O(n)

用广度优先搜索的方式,遍历这棵树。当我们遍历到叶子节点,且此时路径和恰为目标和时,我们就找到了一条满足条件的路径。
……
为了节省空间,我们使用哈希表记录树中的每一个节点的父节点。每次找到一个满足条件的节点,我们就从该节点出发不断向父节点迭代,即可还原出从根节点到当前节点的路径。
……
多少有点麻烦,不推荐.

class Solution {List> ret = new LinkedList>();Map map = new HashMap();public List> pathSum(TreeNode root, int target) {if (root == null) {return ret;}Queue queueNode = new LinkedList();Queue queueSum = new LinkedList();queueNode.offer(root);queueSum.offer(0);while (!queueNode.isEmpty()) {TreeNode node = queueNode.poll();int rec = queueSum.poll() + node.val;if (node.left == null && node.right == null) {if (rec == target) {getPath(node);}} else {if (node.left != null) {map.put(node.left, node);queueNode.offer(node.left);queueSum.offer(rec);}if (node.right != null) {map.put(node.right, node);queueNode.offer(node.right);queueSum.offer(rec);}}}return ret;}public void getPath(TreeNode node) {List temp = new LinkedList();while (node != null) {temp.add(node.val);node = map.get(node);}Collections.reverse(temp);ret.add(new LinkedList(temp));}
}

在这里插入图片描述

3. 参考资料

[1] 二叉树中和为某一值的路径 – 广度优先搜索方法 及 2.1 简化方法来源
[2] 面试题34. 二叉树中和为某一值的路径(回溯法,清晰图解)-- 图片来源

相关内容

热门资讯

桃夭诗经赏析 桃夭诗经赏析  即便只读过很少几篇《诗经》的人,一般也都知道“桃之夭夭,灼灼其华”,那么大家会怎么赏...
曼斯菲尔德《苍蝇》阅读练习及... 曼斯菲尔德《苍蝇》阅读练习及答案  苍蝇  【新西兰】曼斯菲尔德  “你这儿可真舒服。”伍迪菲尔德坐...
李白诗将进酒书法作品 李白诗将进酒书法作品  在《将进酒》这首诗中,小编感受到的是李白一方面对自己充满自信,孤高自傲;另一...
庄子秋水原文以及译文 庄子秋水原文以及译文  秋水选自《庄子·外篇》,《秋水》篇。庄子,姓庄,名周,字子休(亦说子沐),宋...
《上冢宰许公书》原文和译文解... 《上冢宰许公书》原文和译文解析  上冢宰许公①书  何景明  中书舍人②何某顿首,上书冢宰许公下执事...
《小石潭记》文言文精细阅读 高中文言文《游褒禅山记》优秀教案推荐度:《昆虫记》的阅读题附答案推荐度:丑石教案设计推荐度:黄山奇石...
登高丘而望远唐诗翻译及赏析 登高丘而望远唐诗翻译及赏析  登高丘而望远海,六鳌骨已霜,三山流安在?  扶桑半摧折,白日沉光彩。 ...
古籍《海经·海外西经》原文 古籍《海经·海外西经》原文  热爱文学的人,不妨来读古籍吧,下面小编为大家带来了古籍《海经·海外西经...
秦风·无衣的原文及翻译参考 秦风·无衣的原文及翻译参考  岂曰无衣?与子同袍。王于兴师,修我戈矛,与子同仇!<> 岂日无衣?与子...
82个文言文古今异义 82个文言文古今异义  在平日的学习中,大家都背过文言文吧?文言文是与骈文相对的,奇句单行,不讲对偶...
《易经》对中国文化的影响 《易经》对中国文化的影响  《易经》是中华文化的根,大约在新石器时代就诞生了,是中国进入文明社会的重...
《鱼我所欲也》写法介绍及论点 婚恋介绍所的经营模式推荐度:律所新入职自我介绍推荐度:借条的规范写法推荐度:正规借条的写法推荐度:借...
苏轼的《前赤壁赋》原文及翻译 苏轼的《前赤壁赋》原文及翻译  此赋通过月夜泛舟、饮酒赋诗引出主客对话的描写,既从客之口中说出了吊古...
不朽之盛事阅读理解及答案 不朽之盛事阅读理解及答案  不朽之盛事(13分)  ①书写了给人读,人读了书又写书,写了书再给更多的...
杜甫望岳全文及翻译 杜甫望岳全文及翻译  杜甫,字子美,自号少陵野老,唐代伟大的现实主义诗人,与李白合称“李杜”。以下是...
红楼梦诗词鉴赏 红楼梦诗词鉴赏大全  《红楼梦》,中国古典四大名著之首,清代作家曹雪芹创作的章回体长篇小说,又名《石...
《边城》内容梗概 《边城》内容梗概  梗概就是概括文章的主要内容。当你读过一本书或一篇文章时,能用简练的语言把它的主要...
描写场面的词语 关于描写场面的词语  1、喜形于色:形:表现;色:脸色。内心的喜悦表现在脸上。形容抑制不住内心的喜悦...
登高望远的诗句 登高望远的诗句  在日常的学习、工作、生活中,大家一定都接触过一些使用较为普遍的诗句吧,诗句是组成诗...
岳阳楼记的理解性默写 岳阳楼记的理解性默写  《岳阳楼记》超越了单纯写山水楼观的狭境,将自然界的晦明变化、风雨阴晴和“迁客...