为什么迭代链接在链表中以这种方式工作
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
永远不会改变,并且总是指向列表中的第一个元素。
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
永远不会改变,并且总是指向列表中的第一个元素。