七、用 go 语言,给出一个 O(n)时间的非递归过程,实现对一个含 n 个元素的单链表的逆转。要求除存储链表本身所需的空间外,该过程只能使用固定大小的存储空间。
文心一言:
在 Go 语言中,你可以使用迭代方法来反转一个单链表。这种方法只需要 O(1)的额外空间。首先,我们需要定义链表的数据结构:
type ListNode struct {
Val int
Next *ListNode
}
复制代码
然后,我们可以使用以下代码来反转一个链表:
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
curr := head
for curr != nil {
nextTemp := curr.Next //保存下一个节点
curr.Next = prev //反转链接
prev = curr //后移
curr = nextTemp //后移
}
return prev
}
复制代码
这个函数会迭代链表的每个节点,并改变当前节点的 Next 指针以指向它的前一个元素。由于我们需要在更改指针之前保存下一个节点,所以我们需要在更改指针之前将当前节点的 Next 指针保存到临时变量中。
在更改指针后,我们将当前节点和下一个节点向后移动,因此我们可以在 O(1)的空间中反转链表。这个函数的时间复杂度是 O(n),因为它需要遍历链表的每个节点。
讯飞星火:
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
current := head
for current != nil {
nextTemp := current.Next
current.Next = prev
prev = current
current = nextTemp
}
return prev
}
func main() {
// 创建链表:1 -> 2 -> 3 -> 4 -> 5
head := &ListNode{Val: 1}
head.Next = &ListNode{Val: 2}
head.Next.Next = &ListNode{Val: 3}
head.Next.Next.Next = &ListNode{Val: 4}
head.Next.Next.Next.Next = &ListNode{Val: 5}
// 逆转链表
newHead := reverseList(head)
// 打印逆转后的链表:5 -> 4 -> 3 -> 2 -> 1
current := newHead
for current != nil {
fmt.Printf("%d -> ", current.Val)
current = current.Next
}
fmt.Println("nil")
}
复制代码
360 智脑:
以下是一个使用 go 语言实现对单链表进行逆转的 O(n)时间非递归过程:
package main
import "fmt"
// 定义链表节点结构体
type ListNode struct {
Val int
Next *ListNode
}
// 定义链表类
class List {
constructor() {}
reverseList(head: *ListNode) -> *ListNode {
var prev *ListNode = head
var current *ListNode = head.Next
while current != nil {
var next *ListNode = current.Next
current.Next = prev
prev = current
current = next
}
head.Next = prev
return head
}
}
// 测试
var list = new List()
list.add(1)
list.add(2)
list.add(3)
list.add(4)
list.add(5)
fmt.Println("原链表:")
printList(list.head)
list.reverseList(&list.head)
fmt.Println("逆转后的链表:")
printList(list.head)
复制代码
其中,List
是链表类,reverseList
是反转链表的方法。在reverseList
方法中,我们使用两个指针prev
和current
分别指向链表的头节点和当前节点,然后遍历整个链表,每次将当前节点的下一个节点赋值给当前节点,并将当前节点的指针指向前一个节点,最后返回头节点即可。
智谱清言:
package main
import (
"fmt"
)
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
current := head
for current != nil {
nextTemp := current.Next
current.Next = prev
prev = current
current = nextTemp
}
return prev
}
func printList(head *ListNode) {
for head != nil {
fmt.Print(head.Val, "->")
head = head.Next
}
fmt.Println("nil")
}
func main() {
head := &ListNode{Val: 1, Next: &ListNode{Val: 2, Next: &ListNode{Val: 3, Next: &ListNode{Val: 4, Next: &ListNode{Val: 5, Next: nil}}}}}
fmt.Println("Original list:")
printList(head)
reversedHead := reverseList(head)
fmt.Println("Reversed list:")
printList(reversedHead)
}
复制代码
这个程序首先定义了一个 ListNode
结构体,用于表示链表的节点。reverseList
函数接受一个链表的头节点作为参数,并返回逆转后的链表的头节点。
在 reverseList
函数中,我们使用了一个前置节点 prev
,初始值为 nil
。我们从链表的头节点开始,遍历链表的每个节点。对于每个节点,我们保存其下一个节点(nextTemp
),然后将当前节点的前置节点设置为 prev
,将当前节点设置为下一个节点,继续遍历。当遍历到链表的尾部时,current
和 nextTemp
都为 nil
,此时我们将 prev
作为链表的新头节点返回。
printList
函数用于打印链表。我们在 main
函数中创建了一个示例链表,然后调用 reverseList
函数对其进行逆转,并打印原始链表和逆转后的链表。
通义千问:
以下是使用 Go 语言实现的非递归方法,用于逆转一个含 n 个元素的单链表:
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {
prev := nil
curr := head
for curr != nil {
next := curr.Next
curr.Next = prev
prev = curr
curr = next
}
return prev
}
func main() {
head := &ListNode{Val: 1}
head.Next = &ListNode{Val: 2}
head.Next.Next = &ListNode{Val: 3}
head.Next.Next.Next = &ListNode{Val: 4}
head.Next.Next.Next.Next = &ListNode{Val: 5}
fmt.Println("Original List:")
for curr := head; curr != nil; curr = curr.Next {
fmt.Printf("%d ", curr.Val)
}
newHead := reverseList(head)
fmt.Println("\nReversed List:")
for curr := newHead; curr != nil; curr = curr.Next {
fmt.Printf("%d ", curr.Val)
}
}
复制代码
在这个程序中,我们使用三个指针:prev,curr 和 next。prev 指针初始化为 nil,curr 指针初始化为链表的头节点。然后,我们进入一个循环,该循环在 curr 不为 nil 时继续运行。在每次迭代中,我们都做以下操作:
1.将 next 指针设置为 curr 的下一个节点。
2.将 curr 的 next 指针设置为 prev。
3.将 prev 和 curr 向前移动一位。
当我们完成循环时,prev 指针将指向逆转后的链表的头节点。我们返回 prev 指针,这就是逆转后的链表的头节点。
注意,这个程序使用了常数大小的额外空间。
天工:
以下是使用 Go 语言实现 O(n) 时间复杂度的非递归方式逆转单链表的代码:
func reverseList(head *ListNode) *ListNode {
var prev *ListNode = nil
var curr *ListNode = head
for curr != nil {
next := curr.Next
curr.Next = prev
prev = curr
curr = next
}
return prev
}
复制代码
该代码中,我们使用了三个指针,分别是 prev
、curr
和 next
。其中,prev
指向当前节点的前一个节点,curr
指向当前节点,next
指向当前节点的下一个节点。我们从头节点开始遍历链表,每次将当前节点的 next
指针指向 prev
,然后更新 prev
和 curr
的值,继续遍历下一个节点。最后返回 prev
即可。
由于我们只需要常量级别的额外空间,因此空间复杂度为 O(1)。时间复杂度为 O(n),因为我们需要遍历整个链表一次。
chatgpt:
下面是一个使用 Go 语言实现对单链表逆转的非递归过程,时间复杂度为 O(n):
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
current := head
for current != nil {
next := current.Next
current.Next = prev
prev = current
current = next
}
return prev
}
func displayList(head *ListNode) {
current := head
for current != nil {
fmt.Printf("%d ", current.Val)
current = current.Next
}
fmt.Println()
}
func main() {
// 创建一个示例链表 1 -> 2 -> 3 -> 4 -> 5
head := &ListNode{Val: 1}
node2 := &ListNode{Val: 2}
node3 := &ListNode{Val: 3}
node4 := &ListNode{Val: 4}
node5 := &ListNode{Val: 5}
head.Next = node2
node2.Next = node3
node3.Next = node4
node4.Next = node5
fmt.Println("原链表:")
displayList(head)
reversedHead := reverseList(head)
fmt.Println("逆转后的链表:")
displayList(reversedHead)
}
复制代码
这段代码定义了一个ListNode
结构体来表示单链表节点,然后实现了reverseList
函数来对单链表进行逆转。过程中使用了三个指针:prev
用于表示当前节点的前一个节点,current
用于表示当前节点,next
用于保存下一个节点。我们对每个节点进行处理,将当前节点的下一个节点指向前一个节点,然后更新prev
、current
和next
指针。最后返回逆转后的链表的头节点。
在main
函数中,创建了一个示例链表,并调用reverseList
函数对其进行逆转。最后调用displayList
函数来打印原链表和逆转后链表的值,以验证结果。
这个过程的空间复杂度为 O(1),除了存储链表本身所需的空间外,只使用了固定大小的三个指针。
评论