Leetcode - Path Sum

来源:互联网 发布:wps不同表格数据求和 编辑:程序博客网 时间:2024/04/29 08:53

Question

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.


Java Code

public boolean hasPathSum(TreeNode root, int sum) {    LinkedList<Integer> sumList = new LinkedList<Integer>();    allSum(root, sumList);    return sumList.contains(sum);}//版本一,采用DFS,逐条路径记录每个节点与其所有父辈节点之和public void allSum(TreeNode node, LinkedList<Integer> sumList) {    if (node == null) return;    //每遇到一个叶子节点,在sumList中记录该路径的和    if(node.left == null && node.right == null)        sumList.add(node.val);    else {        //右子树为空,只需遍历左子树        if(node.left != null) {            node.left.val += node.val;            allSum(node.left, sumList);        }        //左子树为空,只需遍历右子树        if(node.right != null) {            node.right.val += node.val;            allSum(node.right, sumList);        }    }}//版本二,采用BFS,逐层记录每个节点与其所有父辈节点之和public boolean hasPathSum(TreeNode root, int sum) {    //若输入为空树,则返回假    if(root == null) return false;      LinkedList<Integer> sumList = new LinkedList<Integer>();    LinkedList<TreeNode> nodeList = new LinkedList<>();    //将根节点root和层标志位null入队    nodeList.add(root);    nodeList.add(null);    TreeNode temp, Left, Right;    //如果队列中不是仅剩标志位一个元素    while(nodeList.size() != 1) {        //循环遍历二叉树的每一层,直到遇到层标志位        while ((temp = nodeList.pollFirst()) != null) {            if(temp.left == null && temp.right == null)                sumList.add(temp.val);            else {                  if((Left = temp.left) != null) {                    nodeList.add(Left);//当前节点的左子节点入队                    Left.val += temp.val;//在该左子节点中累加父节点的val                }                if((Right = temp.right) != null) {                    nodeList.add(Right);                    Right.val += temp.val;                }            }        }        //已遍历完一层,在队尾设置新的层标志位        nodeList.add(null);    }    return sumList.contains(sum);}

说明

  • 版本一和二都使用了相同的思想,即每个节点都记录其和所有父辈节点之和,这样每个叶子节点的val即为该条路径下所有节点之和,其中sumList用于记录这个结果,这个方法的副作用是会改变二叉树中每个节点的val。

  • 如果不想有副作用,在版本一代码中,解决方案为给allSum函数多传递一个int类型参数,用于暂存当前节点所有父辈节点的值之和;在版本二代码中,解决方案为将sumList改成两层嵌套的LinkedList,内层的每一个LinkedList用于保存二叉树中每一层的节点值,这里每个节点值都需要累加上其所有父辈节点的值,则遍历完二叉树后,最后一个非空的LinkedList中保存的就是所有不同路径下所有节点之和,但这里会引入一些冗余的操作(所有层的叶子节点都需要传递到最底层),类似的问题可以参考Binary Tree Level Order Traversal 。

  • 需要注意的是,这里不能使用下面这种类似递归方式实现二叉树的先序遍历的终止判断方式,因为此时的node是空节点,但不一定就是叶子节点,类似问题在题目Minimum Depth of Binary Tree

 if(node == null)     sumList.add(node.val);
0 0