[leetcode]树求和的一些题

1.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.

思路:
深度优先的先序遍历,遍历到一个节点时,计算出一个新的value,若该节点是叶子节点,则把这个value加到最终的结果上,否则带着这个值去遍历其左子树和右子树。

代码:

public class Solution {
    int sum=0;
    public int sumNumbers(TreeNode root) {
        if(root==null){
            return 0;
        }
        getNumber(root,0);
        return sum;
    }
    
    public void getNumber(TreeNode root,int value){
        value=value*10+root.val;				//遍历到某一节点,value值的更新
        if(root.left==null&&root.right==null){
            sum=sum+value;
        }
        if(root.left!=null){
            getNumber(root.left,value);
        }
        if(root.right!=null){
            getNumber(root.right,value);
        }
    }
}

更为优雅的思路:
仅采用递归的思想,遍历到某一点时,把该点更新的value值传递给其左子树和右子树,递归结束的条件是,若遍历到一个节点是叶子节点时,则返回其更新的valve值,供父节点归并结果使用。

更为优雅的代码:

public int sumNumbers(TreeNode root) {
    return helper(root,0);
}
private int helper(TreeNode root, int sum)
{
    if(root == null)
        return 0;
    if(root.left==null && root.right==null)
        return sum*10+root.val;
    return helper(root.left,sum*10+root.val)+helper(root.right,sum*10+root.val);
}

2.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.

思路:
先定义一个ArrayList类型的result,result的第0个位置存放当前的最大值,result会不断的被更新。递归求得最大值。
每访问到一个节点的时候,需要递归计算出其左子树的最大路径和右子树的最大路径,然后加上此节点的val(这里还需要将其左子树的最大路径和右子树的最大路径与零相比,只有大于零才与该节点的val值加和,用于更新判断),得到以此节点为根节点的路径值,判断该值是否大于当前的最大值,若大于则把结果放到result的第0位。
递归结束是当一个节点为空节点时,返回路径0;否则,计算过以该节点为根节点的路径值吼,返回左/右路径值和0中较大的值和此节点val的加和。因为若该节点不是根节点时,最终的结果只能是走其左子树或走其右子树。

代码:

public class Solution {
    public int maxPathSum(TreeNode root) {
        if(root==null){
            return 0;
        }
        ArrayList<Integer> result=new ArrayList<Integer>();
        result.add(Integer.MIN_VALUE);
        backtrace(root,result);
        return result.get(0);
    }
    public int backtrace(TreeNode root,ArrayList<Integer> result){
        if(root==null)
            return 0;
        int left=backtrace(root.left,result);
        int right=backtrace(root.right,result);
        int cur=root.val+Math.max(left,0)+Math.max(right,0);
        if(cur>result.get(0)){
            result.add(0,cur);
        }
        return root.val+Math.max(left,Math.max(right,0));
    }
}

3.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.

For example:
Given the below binary tree and sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

思路:
深度优先遍历,当遍历到一个节点时,若该节点是叶子节点,则判断该节点的val值和当前给定的sum值是否相等,若相等,则返回true;否则,用现有的sum值减去本身的val值,传递给其左子树和右子树,递归调用这个函数,但凡左右子树有一个路径和等于传递来的值,即返回true,即 return left||right。

代码:

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

4.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.

For example:
Given the below binary tree and sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
        
return:
[
   [5,4,11,2],
   [5,8,4,5]
]

思路:
同3一样,但需要一个arraylist来保存现有的路径,深度优先遍历该树,访问到一个节点时,若该节点是叶子节点,则需判断该节点的val值和给定的sum值是否相等,若相等,则把该叶子节点添加到arraylist中,并把该arraylist添加到最终结果result中。若遍历的点不是叶子节点,则需要先把该值添加到arraylist中,若其左/右子树不为空,则new一个新的list,把arraylist传递给该list,并更新sum值为当前sum值减去该节点的val值,递归调用该函数。最终返回结果result即可。

代码:

public class Solution {
    public ArrayList<ArrayList<Integer>> result=new ArrayList<ArrayList<Integer>>();
    public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
        if(root==null){
            return result;
        }
        ArrayList<Integer> rowResult=new ArrayList<Integer>();
        getAnswer(rowResult,root,sum);
        return result;
    }
    public void getAnswer(ArrayList<Integer> rowResult,TreeNode root, int sum){
        if(root.left==null&&root.right==null){
            if(root.val==sum){
                rowResult.add(root.val);
                result.add(rowResult);
            }
            return;
        }
        rowResult.add(root.val);
        int value=sum-root.val;
        if(root.left!=null){
            ArrayList<Integer> leftResult=new ArrayList<Integer>(rowResult);
            getAnswer(leftResult,root.left,value);
            //rowResult.remove(rowResult.size()-1);
        }
        if(root.right!=null){
            ArrayList<Integer> rightResult=new ArrayList<Integer>(rowResult);
            getAnswer(rightResult,root.right,value);
        }
        
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41618373/article/details/83786657
今日推荐