剑指 Offer 34. 二叉树中和为某一值的路径

 这题第一反应就是递归,然后虽然磕磕绊绊做出来了,但是时间复杂度惨得要死

 思路如下:

 总的思路就是递归,另外注意如果没有结果返回是空数组,这样也符合递归函数最终的返回值意义

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> result=new ArrayList<>();
        if(root==null)
        {return result;}
        if(root.left==null&&root.right==null)
        {
            if(root.val==sum)
            {
                List list=new ArrayList<>();
                list.add(root.val);
                result.add(list);
                return result;
            }
            else
            {return new ArrayList<>();}   
        }
        
        List<List<Integer>> resultLeft=new ArrayList<>();;
        List<List<Integer>> resultRight=new ArrayList<>();;
        if(root.left!=null)
        {
            resultLeft=pathSum(root.left,sum-root.val);
            if(resultLeft.size()!=0)
            {
                for(List<Integer> list:resultLeft)
                {list.add(0,root.val);}//这里修改了Resultleft的值吗
            }
        }

        if(root.right!=null)
        {
            resultRight=pathSum(root.right,sum-root.val);
            if(resultRight.size()!=0)
            {
                for(List<Integer> list:resultRight)
                {list.add(0,root.val);}//这里修改了Resultleft的值吗
            }
        }

        if(resultRight.size()==0&&resultLeft.size()==0)
        {return new ArrayList<>();}
        else if(resultLeft.size()==0)
        {return resultRight;}
        else if(resultRight.size()==0)
        {return resultLeft;}
        else 
        {
            resultLeft.addAll(resultRight);
            return resultLeft;
        } 
    }
}

相比起来,这种递归的方式更好,因为其中直接在去往叶子节点的路上就建好了list

public List<List<Integer>> pathSum(TreeNode root, int sum) {
    List<List<Integer>> result = new ArrayList<>();
    dfs(root, sum, new ArrayList<>(), result);
    return result;
}

public void dfs(TreeNode root, int sum, List<Integer> list,
                List<List<Integer>> result) {
    //如果节点为空直接返回
    if (root == null)
        return;
    //因为list是引用传递,为了防止递归的时候分支污染,我们要在每个路径
    //中都要新建一个subList
    List<Integer> subList = new ArrayList<>(list);
    //把当前节点值加入到subList中
    subList.add(new Integer(root.val));
    //如果到达叶子节点,就不能往下走了,直接return
    if (root.left == null && root.right == null) {
        //如果到达叶子节点,并且sum等于叶子节点的值,说明我们找到了一组,
        //要把它放到result中
        if (sum == root.val)
            result.add(subList);
        //到叶子节点之后直接返回,因为在往下就走不动了
        return;
    }
    //如果没到达叶子节点,就继续从他的左右两个子节点往下找,注意到
    //下一步的时候,sum值要减去当前节点的值
    dfs(root.left, sum - root.val, subList, result);
    dfs(root.right, sum - root.val, subList, result);
}

https://zhuanlan.zhihu.com/p/112926891

原文地址:https://www.cnblogs.com/take-it-easy/p/14301485.html