为什么迭代链接在链表中以这种方式工作

Why iteration linking works that way in Linked List

Leetcode 上第 19 题的解完全看不懂

所以当我们创建快和慢时 - 我们创建了 link 个头部?我可以判断是的。但是然后我们快速迭代 - 为什么它不改变头部?我的意思是在我们用 fast.next 替换 fast 的每一步?所以不知何故它不会影响头和慢。

然后我们用slow.next替换slow.next。接下来它确实影响了head。

能否请您描述一下它如何不替换第一部分的任何内容并在第二部分替换。

var removeNthFromEnd = function(head, n) {
    let fast = head, slow = head

    for (let i = 0; i < n; i++) fast = fast.next // why it doesn’t change head and slow?

    if (!fast) return head.next

    while (fast.next) fast = fast.next, slow = slow.next
    slow.next = slow.next.next // why it change head?
    return head
 };

变量赋值不会改变对象。

将某些东西分配给 属性 将改变您正在设置的 属性 的对象。

在你的例子中,fast 是一个变量,所以给它赋值,例如 fast.next,永远不会改变对象。它只是改变了 fast 所引用的内容。

另一方面,slow.next 是 属性。给 属性 赋值会改变 slow 引用的对象。

让我们想象一下 fast = fast.next 做了什么。假设 fast 是 3:

列表中的第二个节点

之前:

 head            fast 
  ↓               ↓
┌───────────┐   ┌───────────┐   ┌───────────┐
│ data: B   │   │ data: G   │   │ data: D   │
│ next: ──────> │ next: ──────> │ next: null│
└───────────┘   └───────────┘   └───────────┘

之后:

 head                            fast 
  ↓                               ↓
┌───────────┐   ┌───────────┐   ┌───────────┐
│ data: B   │   │ data: G   │   │ data: D   │
│ next: ──────> │ next: ──────> │ next: null│
└───────────┘   └───────────┘   └───────────┘

现在看看 slow.next = slow.next.next 做了什么。假设 slow 引用第一个节点:

之前:

 slow
 head
  ↓  
┌───────────┐   ┌───────────┐   ┌───────────┐
│ data: B   │   │ data: G   │   │ data: D   │
│ next: ──────> │ next: ──────> │ next: null│
└───────────┘   └───────────┘   └───────────┘

之后:

 slow
 head
  ↓  
┌───────────┐   ┌───────────┐   ┌───────────┐
│ data: B   │   │ data: G   │   │ data: D   │
│ next: ─────┐  │ next: ──────> │ next: null│
└───────────┘│  └───────────┘┌> └───────────┘
             └───────────────┘ 

当您执行 fast = fast.next 时,您正在更改引用变量。 fast 现在指向列表中的下一项。

当您执行 slow.next = slow.next.next 时,您正在更改 slow 指向的对象的 属性。

事实上,在这个例子中,head 永远不会改变,并且总是指向列表中的第一个元素。