Algorithm 查找二叉树中等于和的所有路径

Algorithm 查找二叉树中等于和的所有路径,algorithm,recursion,optimization,time-complexity,binary-tree,Algorithm,Recursion,Optimization,Time Complexity,Binary Tree,例如,给定以下二叉树: [2,3,5,4,8,6,-2,null,null,null,null,null,null,null,2]和sum=7 2 / \ 3 5 / \ / \ 4 8 6 -2

例如,给定以下二叉树:

[2,3,5,4,8,6,-2,null,null,null,null,null,null,null,2]和sum=7

                        2
                      /     \
                    3         5
                 /     \    /   \
                4       8  6     -2
                                  \
                                   2
印刷品:[3,4],[2,5],[2,5,-2,2]

我可以想出一个n^2的解决方案,但是有更好的解决方案吗?可能需要一些额外的内存,比如使用堆栈或哈希表

我花了4个小时试图想出一些解决方案,但所有的解决方案都变得太丑陋或混乱

我的n^2解决方案相对简单: 1) 有一个方法,即helper,它递归地调用自己直到所有的叶子。当它找到包含和的路径时,将其添加到结果中。(这将需要O(n)) 2) 对树中的每个节点调用此方法(O(n)*O(n)=O(n^2))

我的简单解决方案

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

//Solution class
public class Solution {

    public List<List<Integer>> pathSum(TreeNode root, int sum) {

        List<Integer> temp = new ArrayList<Integer>();
        List<List<Integer>> result = new ArrayList<>();

        if (root == null) return result;
        Queue<TreeNode> q = new LinkedList<>();

        q.offer(root);


        while ( !q.isEmpty())
        {
            TreeNode top = q.poll();
            helper(top,sum,temp,result);

            if (top.left != null) q.offer(top.left);
            if (top.right != null) q.offer(top.right);
        }


        return result;
    }

    public void helper(TreeNode root, int sum, List<Integer> temp, List<List<Integer>> result)
    {


    if (root == null) return;
    temp.add(root.val) ;
    if (root.val == sum) 
    {

        result.add(new ArrayList<>(temp));
    }

    helper(root.left,sum-root.val, temp, result );
    helper(root.right, sum-root.val, temp, result);

    temp.remove(temp.size() - 1);

    }

    }

//Execution class
public class treeApp {

public static void main(String args[])
{    TreeNode root = new TreeNode(2);
    root.left = new TreeNode(3);
    root.right = new TreeNode(5);

    root.left.left = new TreeNode(4);
    root.left.right = new TreeNode(8);

    root.right.left = new TreeNode(6);
    root.right.right = new TreeNode(-2);

    root.right.right.right = new TreeNode(2);

    Solution sol = new Solution();

    List<List<Integer>> result ;
    result = sol.pathSum(root, 7);

    for (List l : result)
    {
        System.out.println(l.toString());
    }

}
//Prints:
[2, 5]
[2, 5, -2, 2]
[3, 4]
//树节点结构
公共级树节点{
int-val;
公共树节点左;
公共树节点权;
树节点(intx){val=x;}
}
//解决方案类
公共类解决方案{
公共列表路径和(树节点根,整数和){
List temp=new ArrayList();
列表结果=新建ArrayList();
if(root==null)返回结果;
队列q=新的LinkedList();
q、 报价(根);
而(!q.isEmpty())
{
TreeNode top=q.poll();
助手(顶部、总和、温度、结果);
如果(左上!=null)q.offer(左上);
如果(右上角!=null)q.offer(右上角);
}
返回结果;
}
公共void助手(树节点根、整数和、列表临时值、列表结果)
{
if(root==null)返回;
温度添加(根值);
if(root.val==sum)
{
结果.添加(新ArrayList(temp));
}
助手(root.left、sum-root.val、temp、result);
助手(root.right、sum-root.val、temp、result);
温度移除(温度大小()-1);
}
}
//执行类
公共类treeApp{
公共静态void main(字符串参数[])
{TreeNode root=新的TreeNode(2);
root.left=新的树节点(3);
root.right=新的树节点(5);
root.left.left=新树节点(4);
root.left.right=新树节点(8);
root.right.left=新树节点(6);
root.right.right=新的树节点(-2);
root.right.right.right=新树节点(2);
溶液溶胶=新溶液();
列出结果;
结果=sol.pathSum(根,7);
对于(列表l:结果)
{
System.out.println(l.toString());
}
}
//印刷品:
[2, 5]
[2, 5, -2, 2]
[3, 4]

以任何方便的方式(宽度优先或深度优先)遍历树,但包括指向此节点的路径

在每个节点上,检查在该节点结束的所有路径和;如果任何路径和等于目标值,则将这些路径添加到解决方案中(作为函数结果传回)

然后重复:将当前节点添加到路径并调用每个子节点

这是否足够清楚?我认为这可以在更短的时间内解决问题。遍历是O(N)以到达所有节点。在每个节点上,您通过路径,路径长度为。如果您有一个平衡的二叉树,深度为O(log2[N])