113. Path Sum II

本文探讨了寻找二叉树中所有从根节点到叶子节点的路径,这些路径上的值之和等于给定数的问题。提供了两种不同的实现方法并对比了它们的运行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值