PathSum问题

树的节点结构:

public class TreeNode {
   int val;
   TreeNode left;
   TreeNode right;
   TreeNode(int x) { val = x; }
}

1.Root-to-Leaf Path

(1)判断是否有一条从根到叶子的路径,使得路径和等于某个值
https://leetcode.com/problems/path-sum/
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
思路:不断递归,判断sum值是否等于当前节点值(且当前节点是否为叶子节点),是,返回true

public boolean hasPathSum(TreeNode root, int sum) {
    if(root == null) return false;
    else if(sum == root.val && root.left == null && root.right == null) return true;
    else return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}

(2)从根到叶子的路径使得路径和等于某个值,打印所有这样的路径
https://leetcode.com/problems/path-sum-ii/
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
思路:要找到并打印所有路径,关键在于如何保存路径。设置list保存根到当前节点的路径上所有节点,如果符合条件,将局部list放入全局list中。注意每次加入时要新建list,否则最后局部list会变化

public List<List<Integer>> pathSum(TreeNode root, int sum) {
      List<List<Integer>> ls = new ArrayList<List<Integer>>();//全局list
      List<Integer> local = new ArrayList<Integer>();//局部list
      getPathRecursive(root, sum, local, ls);
      return ls;
}
private void getPathRecursive(TreeNode root, int sum, List<Integer> local, List<List<Integer>> ls){
      if(root == null) return;
      else if(sum == root.val && root.left == null && root.right == null){
            List<Integer> tmp = new ArrayList<Integer>(local);
            tmp.add(root.val);
            ls.add(tmp);
      }
      else{
            int val = root.val;
            local.add(val);
            getPathRecursive(root.left, sum-val, local, ls);
            getPathRecursive(root.right, sum-val, local, ls);
            local.remove(local.size()-1);
      }
}

2.Path-Sum:从根节点开始找到所有路径,使得路径上的节点值和为某一数值(路径不一定以叶子节点结束)并打印路径

(1)判断是否有一条路径,使得路径和等于某个值
思路:不断递归,判断sum值是否等于当前节点值(无需判断是否为叶子节点),是,返回true

public boolean hasPathSum(TreeNode root, int sum) {
    if(root == null) return false;
    else if(sum == root.val) return true;
    else return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}

(2)使得路径和等于某个值,打印所有这样的路径
思路:与上个到叶子节点不同的是,当找到一个符合条件的局部list就放入,并继续找,直到到走不下去了。

public List<List<Integer>> pathSum(TreeNode root, int sum) {
      List<List<Integer>> ls = new ArrayList<List<Integer>>();//全局list
      List<Integer> local = new ArrayList<Integer>();//局部list
      getPathRecursive(root, sum, local, ls);
      return ls;
}
private void getPathRecursive(TreeNode root, int sum, List<Integer> local, List<List<Integer>> ls){
      if(root == null) return;
      else{
            int val = root.val;
            local.add(val);
            if(sum == root.val){
                List<Integer> tmp = new ArrayList<Integer>(local);
                tmp.add(root.val);
                ls.add(tmp);
            }
            getPathRecursive(root.left, sum-val, local, ls);
            getPathRecursive(root.right, sum-val, local, ls);
            local.remove(local.size()-1);
      }
}

3. 从任意一个节点起到任意节点的最大路径值

https://leetcode.com/problems/binary-tree-maximum-path-sum/
Given a binary tree, find the maximum path sum.The path may start and end at any node in the tree.
For example:
Given the below binary tree,

   1
  / \
 2   3
Return 6.

思路:根节点下的路径全局最大值,应该是包含根节点的路径最大值与其之下的全局最优。
用一个全局值记录当前状态下的全局最优,计算到当前节点状态下的全局最优等于包含当前节点的局部最优和全局最优的最大值。
如果不用全局记录就要用一个引用变量传递,比较麻烦。

public int max;
public int maxPathSum(TreeNode root){
        max = Integer.MIN_VALUE;
        calMaxPath(root);
        return max;
}
private int calMaxPath(TreeNode root){
        if(root == null) return 0;
        int right = calMaxPath(root.right);
        int left = calMaxPath(root.left);
        right = right > 0 ? right : 0;
        left = left > 0 ? left : 0;
        localval = root.val + right + left;
        max = max > localval ? localval : max;
        return right > left ? root.val + right : root.val + left;
}

4. 另类规定的所有路径和

https://leetcode.com/problems/sum-root-to-leaf-numbers/
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.
For example,

    1
   / \
  2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.

思路:关键在于求每条路径,只设置一个list即可。注意到叶子节点与到null节点的不同!!

public int sum;
public int sumNumbers(TreeNode root) {
        sum = 0;
        StringBuilder sb = new StringBuilder();
        get(root, sb);
        return sum;
}
public void get(TreeNode root, StringBuilder sb){
        if(root == null) return;
        else if(root.left == null && root.right == null){
            sb.append(root.val);
            int num = Integer.parseInt(sb.toString());
            sum += num;
            sb.deleteCharAt(sb.length()-1);
        }else{
            sb.append(root.val);
            get(root.left, sb);
            get(root.right, sb);
            sb.deleteCharAt(sb.length()-1);
        }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值