文心一言 VS 訊飛星火 VS chatgpt (114)-- 演演算法導論10.2 7題

2023-10-16 18:00:31

七、用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方法中,我們使用兩個指標prevcurrent分別指向連結串列的頭節點和當前節點,然後遍歷整個連結串列,每次將當前節點的下一個節點賦值給當前節點,並將當前節點的指標指向前一個節點,最後返回頭節點即可。

智譜清言:

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,將當前節點設定為下一個節點,繼續遍歷。當遍歷到連結串列的尾部時,currentnextTemp 都為 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
}

該程式碼中,我們使用了三個指標,分別是 prevcurrnext。其中,prev 指向當前節點的前一個節點,curr 指向當前節點,next 指向當前節點的下一個節點。我們從頭節點開始遍歷連結串列,每次將當前節點的 next 指標指向 prev,然後更新 prevcurr 的值,繼續遍歷下一個節點。最後返回 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用於儲存下一個節點。我們對每個節點進行處理,將當前節點的下一個節點指向前一個節點,然後更新prevcurrentnext指標。最後返回逆轉後的連結串列的頭節點。

main函數中,建立了一個範例連結串列,並呼叫reverseList函數對其進行逆轉。最後呼叫displayList函數來列印原連結串列和逆轉後連結串列的值,以驗證結果。

這個過程的空間複雜度為O(1),除了儲存連結串列本身所需的空間外,只使用了固定大小的三個指標。