112.路径总和
自己的思路
class Solution {
public boolean dfs(TreeNode root, int targetSum, int sum){
// if(sum > targetSum){//由于节点值包括正负,所以这个筛选条件不能要
// return false;
// }
if(sum == targetSum && root == null){//过滤的顺序要清楚,两个条件
return true;
}
if(root == null){
return false;
}
return dfs(root.left, targetSum, sum + root.val) || dfs(root.right, targetSum, sum + root.val);
}
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null)
return false;
return dfs(root, targetSum, 0);
}
}
比较简单的思路,当节点为空且sum = targetSum时返回true;
但是这样会出错。
错误
所以不能通过空接点判断要通过叶节点。
修改后
class Solution {
public boolean dfs(TreeNode root, int targetSum, int sum){
if(root == null){
return false;
}
if(root.left == null && root.right == null){//叶节点
return sum + root.val == targetSum;
}
return dfs(root.left, targetSum, sum + root.val) || dfs(root.right, targetSum, sum + root.val);
}
public boolean hasPathSum(TreeNode root, int targetSum) {
return dfs(root, targetSum, 0);
}
}
113.路径总和II
自己的思路
class Solution {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> now = new ArrayList<Integer>();
public void dfs(TreeNode root, int targetSum, int sum){
if(root == null){
return;
}
System.out.println("闲杂遍历的是节点" + root.val);
if(root.left == null && root.right == null){
if(sum + root.val == targetSum){
now.add(root.val);
//ans.add(now);//直接加进去是错误的
ans.add(new LinkedList<Integer>(now));
now.remove(now.size() - 1);
}
return;
}
now.add(root.val);
dfs(root.left, targetSum, sum + root.val);
dfs(root.right, targetSum, sum + root.val);
now.remove(now.size() - 1);
}
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
dfs(root, targetSum, 0);
return ans;
}
}
重要收获
直接用ans.add(now)加进去是空字符串,计算Now不为空也是空字符串
应该要用,ans.add(new ArrayList<Integer>(now));才行
437.路径总和III
自己的思路
主要就是在遍历的时候用一个数组记录前面所有数字的前缀和,
class Solution {
//树形dp?
public int ans = 0;
List<Integer> now = new ArrayList<Integer>();//记录前缀和,是记录前缀和还是记录数字
public void dfs(TreeNode root, int targetSum){
if(root == null){
return;
}
int len = now.size() - 1;//由于我提前放了根节点,所以这里不会为0,至少都会有一个根节点
int sum = now.get(len) + root.val;
now.add(sum);
if(sum == targetSum)//加上了当前root.val是否等于target
ans++;
for(int i = 0; i <= len; i++){
if(sum - now.get(i) == targetSum){//通过前缀和算差
ans++;
}
}
dfs(root.left, targetSum);
dfs(root.right, targetSum);
now.remove(len + 1);
}
public int pathSum(TreeNode root, int targetSum) {
if(root == null){
return ans;
}
now.add(root.val);//加了后都要判断一下是否相等
if(root.val == targetSum){
ans++;
}
dfs(root.left, targetSum);
dfs(root.right, targetSum);
return ans;
}
}
但是错了一个
错误改正
超范围了。将类型给成long
正确代码
要注意输出会耗费很多时间,为了不超时将输出删掉
class Solution {
//树形dp?
public int ans = 0;
List<Long> now = new ArrayList<Long>();//记录前缀和,是记录前缀和还是记录数字
public void dfs(TreeNode root, int targetSum){
if(root == null){
return;
}
int len = now.size() - 1;//至少都会有一个根节点
long sum = now.get(len) + root.val;
now.add(sum);
if(sum == targetSum)
ans++;
for(int i = 0; i <= len; i++){
if(sum - now.get(i) == targetSum){//通过前缀和算差
System.out.println(sum);
System.out.println(now.get(i));
ans++;
}
}
dfs(root.left, targetSum);
dfs(root.right, targetSum);
now.remove(len + 1);
}
public int pathSum(TreeNode root, int targetSum) {
if(root == null){
return ans;
}
now.add((long)root.val);//要先转化成long,让java自动装包为Long
if(root.val == targetSum){//加了后都要判断一下是否相等
ans++;
}
dfs(root.left, targetSum);
dfs(root.right, targetSum);
return ans;
}
}