英文:
Reverse LinkedList in one line
问题
我刚刚在LeetCode上找到了一个使用一行代码的Go语言解决反转链表问题的方法。它确实有效,但我不明白它是如何工作的。
代码如下:
func reverseList(head *ListNode) (prev *ListNode) {
for head != nil {
prev, head, head.Next = head, head.Next, prev
}
return
}
例如,假设链表是 [1->2->3->4->5->nil]
。
我了解到它的工作原理如下:
-
首先执行
head.Next = prev
(head.Next = nil
,所以现在head = [1->nil]
) -
然后,
prev = head
(在这一步中,prev = [1->nil]
,就像前一步中的head
一样) -
head = head.Next
,这里有一个魔法。对于第二步中的prev
,Go语言使用的是head = [1->nil]
,但在这一步之后,head = [2->3->4->5->nil]
因此,只要 head != nil
,它就会迭代,并且在第2步中,prev = [2->1->nil]
,head = [3->4->5->nil]
,依此类推。
这行代码可以表示为:
for head != nil {
a := *head
prev, a.Next = &a, prev
head = head.Next
}
我理解得对吗?为什么它会这样工作?
英文:
I just found a solution for Reverse LinkedList on LeetCode using one line in Go. It realy works, but I can't understand how.
There it is:
func reverseList(head *ListNode) (prev *ListNode) {
for head != nil {
prev, head, head.Next = head, head.Next, prev
}
return
}
For example let the list is [1->2->3->4->5->nil]
.
I got that it's work like:
-
Firstly go execute
head.Next = prev
(head.Next = nil
, so nowhead = [1->nil]
) -
Then,
prev = head
(At this stepprev = [1->nil]
likehead
in previous step) -
head = head.Next
and there is magic. Forprev
on second step Go was usehead = [1->nil]
, but after this stephead = [2->3->4->5->nil]
So while head != nil
it's iterates and at 2nd step prev = [2->1->nil]
, head = [3->4->5->nil]
and so on.
This line can be represented like:
for head != nil {
a := *head
prev, a.Next = &a, prev
head = head.Next
}
Am I right? Why does it work like this?
答案1
得分: 1
表达式左侧的变量在该时刻被赋予右侧表达式的值。这是语言的巧妙运用。
为了更容易理解,让我们通过一个例子来说明。
设置
这是我们的链表:
1 -> 2 -> 3 -> 4 -> nil
在函数执行之前,
- head 是 *Node 1
- prev 是 nil(未初始化)
- head.Next 是 *Node 2
逐步进行
prev, head, head.Next = head, head.Next, prev
让我们来分解一下,
- prev(nil)= head(*Node 1)
- head(*Node 1)= head.Next(*Node 2)
- head.Next(*Node 2)= prev(nil)
下一次迭代,
- prev(*Node 1)= head(*Node 2)
- head(*Node 2)= head.Next(*Node 3)
- head.Next(*Node 3)= prev(*Node 1)
总结
基本上,它将 head.Next
反转到前一个节点,并将 prev 和 head 移动到下一个节点。
将其与 Go 中的教科书算法进行比较,以使其更清晰:
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
for head != nil {
nextTemp := head.Next
head.Next = prev
prev = head
head = nextTemp
}
return prev
}
英文:
Variables on the left side of the expression, are assigned to the values on the right side of the expression at that time. This is a clever use of the language.
To make it easier to understand let's go through an example.
Setup
This is our linked list: <br>
1 -> 2 -> 3 -> 4 -> nil
Before the function is executed,
- head is *Node 1
- prev is nil (uninitialized)
- head.Next is *Node 2
<!--->
Step by step
prev, head, head.Next = head, head.Next, prev
Let's break this down,
- prev (nil) = head (*Node 1)
- head (*Node 1) = head.Next (*Node 2)
- head.Next (*Node 2) = prev (nil)
The next iteration,
- prev (*Node 1) = head (*Node 2)
- head (*Node 2) = head.Next (*Node 3)
- head.Next (*Node 3) = prev (*Node 1)
Summary
Basically, it reverses head.Next
to the previous node and moves prev and head to the next nodes.
Compare this to the textbook algorithm in Go to make it clear: <br>
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
for head != nil {
nextTemp := head.Next
head.Next = prev
prev = head
head = nextTemp
}
return prev
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论