JavaScript的let作用域 和 JavasScript算法与数据结构


#1

最近在leetcode用JavaScript 刷题,碰到了一点不懂的,希望大家点拨一下

var addTwoNumbers = function(l1, l2) {
  let p1 = l1
  let p2 = l2
  let carry = 0
  const dummy = new ListNode()
  let pointer = dummy
  while (p1 || p2 || carry) {
    const num1 = p1 ? p1.val : 0
    const num2 = p2 ? p2.val : 0
    const sum = num1 + num2 + carry
    if (sum > 9) {
      pointer.next = new ListNode(sum % 10)
      carry = 1
    } else {
      pointer.next = new ListNode(sum)
      carry = 0
    }
    if (p1) p1 = p1.next
    if (p2) p2 = p2.next
    pointer = pointer.next
  }
  return dummy.next
};

//作者:hen-ji-shi
//链接:https://leetcode-cn.com/problems/add-two-numbers/solution/js-ya-jie-dian-by-hen-ji-shi/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我的问题如下
let 的块级作用域并不影响他的本地作用域,那么他是如何改变dummy的?为什么是输出dummy.next而不是dummy?


#2

let pointer = dummy 其实是让 pointer 作为 dummy 的指针。因此,修改 pointer 的时候,dummy 不会变。对于题目中的例子,你可以这样考虑:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

最后我们得到的是 dummy -> 7 -> 0 -> 8。然而在计算过程中,我们是先添加 7,然后是 0,最后才是 8。
所以,我们需要一个额外的变量来 track 当前计算到的节点,以便添加后一个节点。
意思是,一开始是 dummy,添加 7。然后把指针移到 7,在这后面添加 0。然后再移到 0,在这后面添加 8。这就是那个 pointer 的作用。

然后你会发现,你一直在操作 pointer,没有动过 dummy。因此,dummy 是不变的,还是指向最开头(7 之前)

LinkedList 的题目,用到 Dummy 节点,绝大部分是返回 dummy.next(暂时想不到什么情况是直接返回 dummy 的)。Dummy 解决的问题是,对于 LinkedList 来说,head 和非 head 需要分别处理。而用了 dummy,就只需要按照非 head 处理,因为 dummy 就是 head。
Dummy 的值是无所谓的,因为这个节点不是结果里面需要的。你可以再考虑下,题目要求是什么,应该返回什么,该不该返回 dummy。像是上面这个例子,我们不需要带着 dummy 一起返回,我们应该返回的是 7 -> 0 -> 8。因此,应该返回 dummy.next