题目描述:
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
提示:
节点总数 <= 10000
注意:本题与主站 113 题相同:https://leetcode-cn.com/problems/path-sum-ii/
解题思路:
(这题被自己蠢哭了)
其实这题很简单,在建立在能够用前序遍历法找出二叉树全部从根节点到叶节点路径的前提下,只要对添加返回路径是增加条件判断路径的和是否和输入的数相等,如果相等则添加到最终的返回列表,否则不添加进返回列表。
前序遍历法得到全部路径的关键在于,先访问当前节点的值,再递归进入当前节点的左子节点,再递归进入当前节点的右子节点(后序遍历和中序遍历都是相似的思路)。需要注意的是,所有的路径都共用一个list列表,每一层递归之后,需要将list的最后一个元素删除了,否则路径中会包含其他路径的节点。
代码(Java):
import java.util.ArrayList;
import java.util.List;
public class doingmyself {
public static void main(String[] args) {
TreeNode root = new TreeNode(5);
root.left = new TreeNode(4);
root.right = new TreeNode(8);
root.left.left = new TreeNode(11);
root.left.left.left = new TreeNode(7);
root.left.left.right = new TreeNode(2);
root.right.left = new TreeNode(13);
root.right.right = new TreeNode(4);
root.right.right.left = new TreeNode(5);
root.right.right.right = new TreeNode(1);
int sum = 22;
List<List<Integer>> ans = pathSum(root, sum);
System.out.println(ans);
// List<List<Integer>> pre = preorder(root);
// System.out.println(pre);
}
static List<List<Integer>> res = new ArrayList<>();
static List<Integer> list = new ArrayList<>();
//前序遍历法找到二叉树的全部路径
public static List<List<Integer>> preorder(TreeNode root){
dfs(root); //递归遍历节点
return res;
}
//递归访问节点
public static void dfs(TreeNode root){
if(root == null) return; //如果当前节点是空的,直接返回到上级节点
list.add(root.val); //只要当前节点不是空的,就把这个节点的值添加到列表list中
if(root.left == null && root.right == null){ //判断当前这个节点是不是叶节点,如果是叶节点,当前路径就已经完整了,list添加到res中
res.add(new ArrayList(list));
}
dfs(root.left); //递归访问当前节点的左子节点
dfs(root.right); //递归访问当前节点的右子节点
list.remove(list.size()-1); //返回上层递归的之前,要把list最后一个元素删除了,否则路径就有了其他路径的元素
}
//在前序遍历发得到所有的路径的同时,判断路径的和是否符合要求,如果符合需要的,就添加到返回的列表中
public static List<List<Integer>> pathSum(TreeNode root, int sum){
recur(root, sum);
return res;
}
public static void recur(TreeNode root, int remain){
if(root == null){
return;
}
list.add(root.val);
remain = remain - root.val; //每次将路径和的值减去当前节点的值
if(remain == 0 && root.left == null && root.right == null){ //如果remain的值变为0的时候,同时当前节点也是叶节点,则把list添加到res中
res.add(new ArrayList(list));
}
recur(root.left, remain);
recur(root.right, remain);
list.remove(list.size()-1);
}
}
class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}