关于leetcode中路径总和的几道题目的整理。
路径总和I
题目描述: 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
解题思路:递归,sum值每次递归减去其根结点的值
java代码:
1
class Solution {
2
public boolean hasPathSum(TreeNode root, int sum) {
3
if (root == null)
4
return false;
5
sum -= root.val;
6
if (root.left == null && root.right == null) {
7
return sum == 0;
8
}
9
return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
10
}
11
}
路径总和II
题目描述: 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
解题思路:递归,利用一个数组保存遍历的路径,如果遇到根结点并且满足条件则输出。
java代码:
1
class Solution {
2
public List<List<Integer>> pathSum(TreeNode root, int sum) {
3
List<List<Integer>> ans = new ArrayList<>();
4
List<Integer> arry = new ArrayList<>();
5
dfs(root, sum, arry, ans);
6
return ans;
7
}
8
9
public void dfs(TreeNode root, int sum, List<Integer> arry, List<List<Integer>> ans) {
10
if (root == null) return;
11
arry.add(root.val);
12
sum -= root.val;
13
if (root.left == null && root.right == null && sum == 0) {
14
//ans.add(arry); //整个递归过程用的是同一个arry,需要把当前的状态保存下来,否则最后的输出全为空[]
15
ans.add(new ArrayList<>(arry));
16
}
17
dfs(root.left, sum, arry, ans);
18
dfs(root.right, sum, arry, ans);
19
arry.remove(arry.size() - 1);//回溯,去除当前的根结点,继续寻找下一个满足条件的路径
20
}
21
}
路径总和III
题目描述:给定一个二叉树,它的每个结点都存放着一个整数值。找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。
解题思路:
- 思路1:递归,从每一个节点出发,找到所有满足条件的路径,两层递归。
- 思路2:考虑到每个节点到根节点的路径是唯一的。用一维数组保存当前节点到根节点的所有路径,用一个标记表示当前路径的终点。
java代码:
1
class Solution {
2
//思路1 双重递归
3
//先序遍历每一个结点,在以每一个节点作为起始节点递归查找
4
private int num = 0;
5
public int pathSum(TreeNode root, int sum) {
6
if (root == null) return 0;
7
cal_sum(root, sum);
8
pathSum(root.left, sum);
9
pathSum(root.right, sum);
10
return num;
11
}
12
//计算当前结点作为根结点的所有满足的路径
13
public void cal_sum(TreeNode root, int sum) {
14
if (root == null) return;
15
sum -= root.val;
16
if (sum == 0) {
17
num++;
18
}
19
cal_sum(root.left, sum);
20
cal_sum(root.right, sum);
21
}
22
}
1
class Solution {
2
//思路2
3
/**核心:每个节点到根节点的路径是唯一的
4
* 1.用一维数组保存当前节点到根节点的所有路径
5
* 2.用一个标记表示当前路径的终点
6
* 3.先序遍历所有节点
7
*/
8
public int pathSum(TreeNode root, int sum) {
9
return cal_sum(root, sum, new int[1000], 0);
10
}
11
//arry数组用于保存遍历过的路径
12
public int cal_sum(TreeNode root, int sum, int arry[], int p) {
13
if (root == null) return 0;
14
int n = (root.val == sum ? 1 : 0); //判断单独的节点是否满足条件
15
int cur = root.val;
16
for (int i = p - 1; i >= 0; i--) { //根结点出发到当前结点的所有可能值
17
cur += arry[i];
18
if (cur == sum) {
19
n++;
20
}
21
}
22
arry[p] = root.val; //访问过的结点加入数组
23
int n1 = cal_sum_2(root.left, sum, arry, p + 1);
24
int n2 = cal_sum_2(root.right, sum, arry, p + 1);
25
return n + n1 + n2;
26
}
27
}