作者 | 小鹿
来源 | 小鹿动画学编程
题目
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输出整数的所有路径。从树的根节点开始往下一直到叶子节点所经过的节点形成一条路径。
如图:
题目分析
要想知道二叉树的某一路径和是否等于一个整数,那么首先要全部列举出所有路径和,然一一对比找出满足条件的路径。
那么什么方法可以遍历出二叉树所有路径的情况呢?我们第一可能想到的是二叉树的三种遍历方式,前、中、后遍历,因为我们路径和是从根到叶子节点的,通过这个特点,我们可以一下子定位到前序遍历的顺序特点(根、左、右),遍历规律从根到叶子节点逐个进行递归遍历,符合我们所分析的。
通过上方我们选择前序遍历来进行求路径和。我们可以声明一个数组,每遍历一个节点,我们就推进数组,当遇到根节点时,我们就将数组求和,判断是否等于我们的目标值,如果不相等,我们就返回上一个节点,同时数组中的数据出栈一个,然后将下一个遍历到的节点加入到数组中。
这种“先进先出”的特点让我们想到了一个数据结构就是“栈”,没错,我们正是用这种结构来进行解决此题。
动画实现
解题思路
首先,用户输入当前树和整数值,我们要进行判断。
// 判断当前树和值是否为正常值
if(root == null || value 0){
return false;
}
然后我们开始声明用到的一些变量,比如路径栈、符合条件的路径存储数组以及当前累积的值。
// 声明变量
let pathStack = [],
currentSum = 0,
result = [];
开始遍历路径,整体的逻辑思路俺已经整理好。首先我们拿到当前节点,我们要把当前节点的值入栈,然后判断栈内的和是否等于我们输入的整数值且当前节点为叶子节点。如果是,则将路径输出到结果集中,否则,继续进行对当前节点的左右子树往下递归,如果遇到叶子节点,且当前的值不符合条件,我们就出栈,返回上一个节点继续进行递归。
// 遍历路径
const FindPath = (root, value, currentSum, pathStack, result)=>{
// 累加
currentSum = currentSum + root.val;
// 入栈
pathStack.push(root.val);
// 判断是否等于目标值且为叶子节点
if(currentSum == value && root.left == null && root.rigth == null){
result = pathStack;
return result;
}
// 如果不是,则判断是有子节点进行递归
if(root.left !== null){
FindPath(root.left, value, currentSum, pathStack, result);
}
if(root.rigth !== null){
FindPath(root.rigth, value, currentSum, pathStack, result);
}
// 递归出栈
pathStack.pop();
}
代码实现
JavaScript
Java
Python
测试用例
- 完全二叉树、非完全二叉树(有一条路径满足、有多条路径满足、都不满足)—— 普通测试。
- 只有左子节点的二叉树、只有右子节点的二叉树、只有一个结点的二叉树 —— 特殊测试。
- 空二叉树、输入负数 —— 输入测试。
------ END ---------
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。关注公众号并回复 888 领取