113. Path Sum II

来源:互联网 发布:网络传输介质各自特点 编辑:程序博客网 时间:2024/06/04 20:05
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]
]
求二叉树中所有根到叶子节点的值的和等于指定数字的路径

题目不难 注意两种写法的区别 


第一种 我写的

public List<List<Integer>> pathSum(TreeNode root, int sum) {    List<List<Integer>> res = new ArrayList<>();    pathSum(root, new ArrayList<>(), sum, res);    return res;}private void pathSum(TreeNode root, List<Integer> cur, int sum, List<List<Integer>> res) {    if (root == null) return;    cur.add(root.val);    sum -= root.val;    if (root.left == null && root.right == null && sum == 0) {        res.add(new ArrayList<>(cur));        return;    }    pathSum(root.left, new ArrayList<>(cur), sum, res);//1.    pathSum(root.right, new ArrayList<>(cur), sum, res);}

每次都把当前节点的值加入到cur中 当cur满足和等于sum 添加到结果集res中
平均runtime 6ms 

第二种 discuss中看到的 平均runtime 3ms
public List<List<Integer>> pathSum(TreeNode root, int sum) {    if(root == null){        return new ArrayList<>();    }    List<List<Integer>> result = new ArrayList<>();    List<Integer> list = new ArrayList<>();    dfs(root, sum, result, list);    return result;}private void dfs(TreeNode node, int sum, List<List<Integer>> result, List<Integer> list){    list.add(node.val);    sum = sum - node.val;    if(node.left == null && node.right == null && sum == 0){        result.add(new ArrayList<>(list));    }    if(node.left != null){        dfs(node.left, sum , result, list);    }    if(node.right != null){        dfs(node.right, sum, result, list);    }    sum = sum + node.val;//1.    list.remove(list.size() - 1); }

主要区别就是1.处
因为保存当前路径的集合list 后面也在重复利用 为了避免他们的互相产生影响
(比如遍历左子树 右子树 都会向list中添加元素)
有两种解决办法
1.向下传递list的时候 新建一个集合 把list的元素放进去
2.本层递归执行完毕后 把刚才添加进来的元素删掉
我采用的是1 discuss采用的是2 

为什么2比较快呢 我一开始以为是 
new ArrayList<>(cur);
时间复杂度是O(n), 会把cur中的元素逐一copy进新建的集合 看了list的源码发现不是的
public ArrayList(Collection<? extends E> c) {    elementData = c.toArray();    if ((size = elementData.length) != 0) {        // c.toArray might (incorrectly) not return Object[] (see 6260652)        if (elementData.getClass() != Object[].class)            elementData = Arrays.copyOf(elementData, size, Object[].class);    } else {        // replace with empty array.        this.elementData = EMPTY_ELEMENTDATA;    }}

因为list的底层实现是Object数组 所以这行代码会直接把新集合的数组替换成cur的数组 时间复杂度O(1)
只有
elementData.getClass() != Object[].class
才会逐个copy

慢的原因应该是新建集合的消耗



原创粉丝点击