题目链接
牛客网在线oj题——二叉树中和为某一值的路径(二)
题目描述
输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
如二叉树root为{10,5,12,4,7},expectNumber为22
则合法路径有[[10,5,7],[10,12]]
数据范围:
树中节点总数在范围 [0, 5000] 内
-1000 <= 节点值 <= 1000
-1000 <= expectNumber <= 1000
题目示例
示例1
输入:
{10,5,12,4,7},22
返回值:
[[10,5,7],[10,12]]
说明:
返回[[10,12],[10,5,7]]也是对的
示例2
输入:
{10,5,12,4,7},15
返回值:
[]
示例3
输入:
{2,3},0
返回值:
[]
示例4
输入:
{1,3,4},7
返回值:
[]
解题思路
这道题需要通过深度搜索,回溯实现,分为下面几个步骤
- 添加节点的值
- 判断是否满足条件,如果满足则将当前结果添加到结果集中
- 继续深度搜索
- 判断是否越界,如果越界则回退到上一个状态
定义一个ArrayList<ArrayList< Integer>> result变量,用于存储最终的结果
定义一个ArrayList< Integer> list变量,用于存储一次遍历时的过程集合
实现深度优先算法FindPathDFS(TreeNode root, int expectNumber, ArrayList<ArrayList< Integer>> result, ArrayList< Integer> list),参数分别为:当前递归到的节点,当前期待数字和,结果集result,过程集list,没有返回值
首先判断root是否为空,如果为空则直接返回
然后将当前root.val 添加到过程集中
更新目标值, expectNumber -= root.val;
如果当前root没有左子树和右子树(当前为叶子节点),并且expectNumber == 0(当前分支的所有数字和为expectNumber),则将list添加到result中
递归调用该函数,传入左子树和右子树
最后如果当前list不满足条件,则直接返回到上一个状态:list删除掉最后一个元素,list.remove(list.size() - 1);
完整代码
import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int expectNumber) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(root == null){
return result;
}
FindPathDFS(root, expectNumber, result, new ArrayList<>());
return result;
}
private void FindPathDFS(TreeNode root, int expectNumber, ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) {
if(root == null){
return;
}
list.add(root.val);
expectNumber -= root.val;
if(root.left == null && root.right == null && expectNumber == 0){
result.add(new ArrayList<>(list));
}
FindPathDFS(root.left, expectNumber, result, list);
FindPathDFS(root.right, expectNumber, result, list);
list.remove(list.size() - 1);
}
}