一道leetcode题引发的思考

leetcode每日一题疑惑

今天的leetcode每日一题129. 求根到叶子节点数字之和

看完题以后想了种解法(比较繁琐,层序遍历,记录到根节点的所有数字,最后再求和),不要在意细节,看完题解发现自己写的太复杂了,此文不讨论算法,记录下其中的一个疑惑,希望有大佬给解答下。

先上代码

func sumNumbers(root *TreeNode) int {
    if root == nil {
        return 0
    }
    numbers := [][]int{}
    // 遍历所有到叶子节点的路径,存到numbers中
    queue := make([]*TreeNode, 0)
    queue = append(queue, root)
    values := make([][]int, 0)
    values = append(values, []int{root.Val})
    for len(queue) > 0 {
        q := queue[0]
        v := values[0]
        queue = queue[1:]
        values = values[1:]
        if q.Left == nil && q.Right == nil {
            numbers = append(numbers, v)
        }
        if q.Left != nil {
            queue = append(queue, q.Left)
            // tempV := make([]int, len(v))
            // copy(tempV, v)
            values = append(values, append(v, q.Left.Val))
        }
        if q.Right != nil {
            queue = append(queue, q.Right)
            // tempV := make([]int, len(v))
            // copy(tempV, v)
            values = append(values, append(v, q.Right.Val))
        }
    }
    ans := 0
    for _, number := range numbers {
        sum := 0
        for i := 0; i < len(number); i++ {
            sum = sum*10 + number[i]
        }
        ans += sum
    }
    return ans
}

给的用例通过了,于是提交,发现卡在这个用例上

一道leetcode引发的思考

debug以后,发现在进行到其中某一步的时候values中第一个切片最后一个元素本来是9,后来变成5了,不明白咋回事

原来values [[8,3,9,9]],append一个切片[8,3,9,5]以后应该是[[8,3,9,9], [8,3,9,5]],可是变成了[[8,3,9,5], [8,3,9,5]],导致结果出错,应该是切片的问题,不太明白,谁能解释一下其中的原因,为啥原有的数据会被改变,感谢大佬。

注释掉的是后来把切片copy了下,问题解决了,知道是切片问题,没想明白为啥。

提供下出错用例的树形结构供debug

type TreeNode struct {
    Val int
    Left *TreeNode
    Right *TreeNode
}
//      8
//     / \
//    3   5
//     \  
//      9 
//        /  \      
//    9    5     
func main() {
    node5 := &TreeNode{Val: 5}
    node52 := &TreeNode{Val: 5}
    node92 := &TreeNode{Val: 9}
    node9 := &TreeNode{Val: 9, Left: node92, Right: node52}
    node3 := &TreeNode{Val: 3, Left: nil, Right: node9}
    node8 := &TreeNode{Val: 8, Left: node3, Right: node5}
    fmt.Println(sumNumbers(node8))
    // 输出结果:16875
    // 正确结果:16879
}

原文链接 129. 求根到叶子节点数字之和

讨论数量: 2
pardon110

基本上

  • 当需要的容量超过原切片容量的两倍时,会使用需要的容量作为新容量。
  • 当原切片长度小于1024时,新切片的容量会直接翻倍。
  • 而当原切片的容量大于等于1024时,会反复地增加25%,直到新容量超过所需要的容量。

为避免因切片是否发生扩容导致bug,最好在必要时使用 copy 来复制数据,保证得到一个新的切片,以避免后续操作带来预料之外的副作用。或者这样直接使用递归,通过值传递实现

func sumNumbers(root *TreeNode) int {
    var rs int
    var dfs func(*TreeNode, int)
    dfs = func(root *TreeNode, sum int){
        if root == nil {
            return 
        }
        sum = sum *10 + root.Val
        if root.Left == nil && root.Right == nil {
            rs += sum
        }
        dfs(root.Left, sum)
        dfs(root.Right, sum)
    }
    dfs(root,0)
    return rs
}
3年前 评论

@pardon110 嗯,开始想复杂了,直接存值就可以了,只是用切片过程中出现这个问题,切片扩容我了解,就是按照我的题解一步一步debug有点绕进去了,想的头疼 :joy: 非常感谢🙏

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!