我对head.next如何返回整个列表而不是下面代码中的下一个值(如l1、l2、dummy.next(感到困惑。特别是我想知道head.next是如何返回整个排序数组并跳过第二行输入的-1值的。
let mergeTwoLists = function (l1, l2) {
let dummy = new ListNode(-1);
let head = dummy;
while (l1 !== null && l2 !== null) {
if (l1.val <= l2.val) {
dummy.next = l1;
l1 = l1.next;
} else {
dummy.next = l2;
l2 = l2.next;
}
dummy = dummy.next;
}
if (l1 !== null) {
dummy.next = l1;
} else {
dummy.next = l2;
}
return head.next;
};
class ListNode {
constructor(val = null, next = null) {
this.val = val;
this.next = next;
}
}
也许这有助于可视化列表的构建方式:
让输入是一个值为[3,9]的列表,另一个值仅为[4]的列表:
l1
↓
3 → 9 → null
l2
↓
4 → null
在循环开始之前,将创建一个新节点:
head
↓
-1
↑
dummy
循环将进行第一次迭代,并且if
条件为true。第一个dummmy.next
被适配,这导致了这种情况:
head l1
↓ ↓
-1 → 3 → 9 → null
↑
dummy
l2
↓
4 → null
然后CCD_ 3被重新分配一个新的参考:
head l1
↓ ↓
-1 → 3 → 9 → null
↑
dummy
l2
↓
4 → null
循环中的最后一条语句为dummy
:分配了一个新的引用
head l1
↓ ↓
-1 → 3 → 9 → null
↑
dummy
l2
↓
4 → null
循环第二次迭代,if
条件现在为false,因此我们进入else
块。首先对dummmy.next
进行了调整(这打破了它与l1
的联系,因此我移动了l1
和l2
的可视化(:
head l2
↓ ↓
-1 → 3 → 4 → null
↑
dummy
l1
↓
9 → null
然后l1
被重新分配一个新的参考,在这种情况下,它变成null
:
head l2
↓ ↓
-1 → 3 → 4 → null
↑
dummy
l1
↓
9 → null
循环中的最后一条语句为dummy
:分配了一个新的引用
head l2
↓ ↓
-1 → 3 → 4 → null
↑
dummy
l1
↓
9 → null
在此阶段,循环条件不再为真(l2
为null
(,因此执行循环之后的if
块。这将dummy.next
与剩余(而非null
(引用链接起来。同样,为了可视化,我交换了l1
和l2
:的位置
head l1
↓ ↓
-1 → 3 → 4 → 9 → null
↑
dummy
l2
↓
null
现在我们来看最后一句话:return head.next
。请注意,head
从未离开在开始时创建的新节点。
所以返回的参考是:
head l1
↓ ↓
-1 → 3 → 4 → 9 → null
↑
returned
l2
↓
null
请注意head
在整个函数执行过程中是如何一直指向带-1的节点的。值为-1的临时节点将被垃圾回收,因为一旦函数返回(head
是本地变量(,就没有变量再引用它了。