给定二叉树和求和,找到所有根到叶的路径,其中每条路径的总和等于给定的总和

时间:2015-08-14 04:24:19

标签: java binary-tree

为什么" path.remove(path.size() - 1)"到底用过了什么?

此代码用于查找总和等于给定总和的所有根到叶路径。

local_item_size

删除" path.remove(path.size() - 1);"从代码中将给出以下输出。

输入:[0,1,1],1

输出:[[0,1],[0,1,1]] ==>这是错误的输出

预期输出:[[0,1],[0,1]]

3 个答案:

答案 0 :(得分:1)

path正在从path.add(root.val);列表中删除最后添加的节点,因为您正在为所有递归迭代重用相同的列表,并在每个方法中添加public void pathSumRe(TreeNode root, int sum, List<List<Integer>> res, ArrayList<Integer> path) { if (root == null) { return; } path.add(root.val); if (root.left == null && root.right == null && root.val == sum) { res.add(new ArrayList<Integer>(path)); } pathSumRe(root.left, sum - root.val, res, new ArrayList<Integer>(path)); pathSumRe(root.right, sum - root.val, res, new ArrayList<Integer>(path)); } 的当前节点执行。

如果不重复使用相同的列表(并为每次执行创建一个新列表),以下内容将是等效的:

ArrayList

这更容易理解,但会创建更多新的class TreeNode { public final int val; public final TreeNode left; public final TreeNode right; public TreeNode(int val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } } (取决于树结构)。 无论您的编辑如何,两个版本都可以正常运行TreeNode,如下所示:

integer

答案 1 :(得分:0)

这是干净的Java实现:

public static List<List<Integer>> rootToLeafPathsForSum(BinaryTreeNode<Integer> node, int requiredSum) {
    List <List<Integer>> paths = new ArrayList<List<Integer>>();
    doFindRootToLeafPathsForSum(node, 0, requiredSum, new ArrayList<Integer>(), paths);
    return paths;
}

private static void doFindRootToLeafPathsForSum(BinaryTreeNode<Integer> node, int sum, int requiredSum,
        List<Integer> path, List<List<Integer>> paths) {
    if(node == null) {
        return ;
    } 
    path.add(node.getData());
    sum +=node.getData();
    if (node.isLeafNode()) {
        if (sum == requiredSum) {
            paths.add(new ArrayList<Integer>(path));
        }           
    } else {
        doFindRootToLeafPathsForSum(node.getLeft(), sum,  requiredSum, path, paths);
        doFindRootToLeafPathsForSum(node.getRight(), sum, requiredSum, path, paths);

    }
    path.remove(node.getData());
}

以下是测试用例

@Test
public void allRoot2LeafPathsForGivenSum() {
    BinaryTreeNode<Integer> bt = buildTree();
    List <List<Integer>> paths = BinaryTreeUtil.rootToLeafPathsForSum(bt, 14);

    assertThat(paths.size(), is(2));

    assertThat(paths.get(0).toArray(new Integer[0]), equalTo(new Integer[]{1,2,5,6}));
    assertThat(paths.get(1).toArray(new Integer[0]), equalTo(new Integer[]{1,3,7,3}));

    for (List<Integer> list : paths) {          
        for (Integer integer : list) {
            System.out.print(String.format(" %d", integer));
        }
        System.out.println();
    }
}

private BinaryTreeNode<Integer> buildTree() {
    BinaryTreeNode<Integer> n4 = new BinaryTreeNode<Integer>(4);
    BinaryTreeNode<Integer> n6 = new BinaryTreeNode<Integer>(6);
    BinaryTreeNode<Integer> n5 = new BinaryTreeNode<Integer>(5, null, n6);
    BinaryTreeNode<Integer> n2= new BinaryTreeNode<Integer>(2, n4, n5);
    BinaryTreeNode<Integer> n31 = new BinaryTreeNode<Integer>(3);
    BinaryTreeNode<Integer> n7 = new BinaryTreeNode<Integer>(7, null, n31);
    BinaryTreeNode<Integer> n3 = new BinaryTreeNode<Integer>(3, n7, null);
    BinaryTreeNode<Integer> root = new BinaryTreeNode<Integer>(1, n2, n3);

    return root;
}

答案 2 :(得分:0)

您需要的是检查到目前为止所遍历路径的方法,如果是,则将其加总直到叶子加总,如果是,则添加该列表以得到结果,否则不需要回溯,这是本例中最重要的步骤!我希望代码能使它更清晰-

void util(TreeNode root, int sum, ArrayList<Integer>log, ArrayList<ArrayList<Integer>> result)
{
    if(root == null)    
        return;
    log.add(root.val);
    if(root.left == null && root.right == null && sum - root.val == 0)
        result.add(new ArrayList<Integer>(log));
    util(root.left, sum-root.val, log, result);
    util(root.right, sum-root.val, log, result);
    log.remove(log.size()-1);
}