Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where the sum of the node values in the path equals targetSum. Each path should be returned as a list of the node values, not node references.
A root-to-leaf path is a path starting from the root and ending at any leaf node. A leaf is a node with no children.
Example 1:
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
Output: [[5,4,11,2],[5,8,4,5]]
Explanation: There are two paths whose sum equals targetSum:
5 + 4 + 11 + 2 = 22
5 + 8 + 4 + 5 = 22
Example 2:
Input: root = [1,2,3], targetSum = 5
Output: []
Example 3:
Input: root = [1,2], targetSum = 0
Output: []
Constraints:
The number of nodes in the tree is in the range [0, 5000].
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
这题我们提供多个思路尝试解答,看看各自的执行效率。
第一个我们用后续遍历的写法。
拿到这个题相信大家都会想到,我们需要计算总和,或者相减最后的那个数等于root.val,这个时候我们可以直接找到最后的叶子结点同时这个叶子结点的值还等于targetSum。这里是一个结果,同时还要完成的是递归找到所有左子树的结点和右子树的结点,利用后续遍历进行求解。
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
//第一步我们也是需要判断是否为空
if(root == null){
return new ArrayList<>();
}
//创建一个List用来存储结果
List<List<Integer>> res = new ArrayList<>();
//现在我们面临的问题是找到多个可达路径,所以需要先找到末尾结点,并判断尾结点是否等于targetSum
//这条语句执行之后得到的结果肯定就是输出结果
if(root.left != null && root.right != null && targetSum == root.val){
//如果相等
List<Integer> list = new ArrayList<>();
list.add(root.val);
res.add(list);
return res;
}
//上面这几条语句如果不递归的花最后可能只会是一个数而不是一组数
List<Integer> left = pathSum(root.left,targetSum - root.val);
List<Integer> right = pathSum(root.right,targetSum - root.val);
//这个时候所有的有效数据都存储在这两个结点里面了
//后续遍历输出
for(List<Integer> l1 : left){
l1.add(0,root.val);
res.add(l1);
}
for(List<Integer> l2 : right){
l2.add(0,root.val);
res.add(l2);
}
return res;
}
}
然后我们再看看如何用BFS进行解题
class Solution {
//使用广度优先的话我们需要两个方法,所以此时在外面定义全局变量
List<List<Integer>> res = new ArrayList<>();
//为了节省空间,使用Map存储父节点
Map<TreeNode,TreeNode> map = new HashMap<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
//使用两个队列进行存储节点和节点的值
Queue<TreeNode> queue1 = new LinkedList<>();
Queue<Integer> queue2 = new LinkedList<>();
queue1.add(root);
queue2.add(0);
//当队列不为空
while(!queue1.isEmpty()){
TreeNode node = queue1.poll();
int number = queue2.poll() + node.val;//注意需要家node.val这是为了计算总值
if(node.left == null && node.right == null){
if(number == targetNum){
getPath(node);
}
} else {
if(node.left != null){
//map存储父节点
map.put(node.left,node);
queue1.add(node.left);
queue2.add(num);
}
if(node.right != null){
//map存储父节点
map.put(node.right ,node);
queue1.add(node.right );
queue2.add(num);
}
}
}
return ret;
}
public void getPath(TreeNode node) {
List<Integer> temp = new LinkedList<Integer>();
while (node != null) {
temp.add(node.val);
node = map.get(node);
}
Collections.reverse(temp);//注意需要反转链表
ret.add(new LinkedList<Integer>(temp));
}
}
再看看深度优先
class Solution {
List<List<Integer>> ret = new LinkedList<List<Integer>>();
Deque<Integer> path = new LinkedList<Integer>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
dfs(root, targetSum);
return ret;
}
public void dfs(TreeNode root, int targetSum) {
if (root == null) {
return;
}
path.offerLast(root.val);
targetSum -= root.val;
if (root.left == null && root.right == null && targetSum == 0) {
ret.add(new LinkedList<Integer>(path));
}
dfs(root.left, targetSum);
dfs(root.right, targetSum);
path.pollLast();
}
}