在一行中反转链表

huangapple go评论84阅读模式
英文:

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]

我了解到它的工作原理如下:

  1. 首先执行 head.Next = prevhead.Next = nil,所以现在 head = [1->nil]

  2. 然后,prev = head(在这一步中,prev = [1->nil],就像前一步中的 head 一样)

  3. 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:

  1. Firstly go execute head.Next = prev (head.Next = nil, so now head = [1->nil])

  2. Then, prev = head (At this step prev = [1->nil] like head in previous step)

  3. head = head.Next and there is magic. For prev on second step Go was use head = [1->nil], but after this step head = [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
}

huangapple
  • 本文由 发表于 2023年6月1日 06:07:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定