題目:從尾到頭打印鏈表node
要求:輸入一個鏈表的頭節點,從尾到頭反過來返回每一個節點的值(用數組返回)。數組
示例:數據結構
`app
輸入:head = [1,3,2]函數
輸出:[2,3,1]性能
`spa
限制:code
0 <= 鏈表長度="" <="10000 cdn
由於是從尾到頭返回每個節點的值,因此很容易想到若是從最後的節點將值放入數組中,而後再往前逐步將數據放入數組,最後回到頭節點返回便可,能夠想到遞歸就能輕鬆作到,只要注意遞歸函數的結束條件便可。blog
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reversePrint(head *ListNode) []int {
if head == nil {
return nil
}
return appendData(head)
}
func appendData(head *ListNode) []int {
if head.Next != nil{
list := appendData(head.Next)
list = append(list, head.Val)
return list
}
return []int{head.Val}
}複製代碼
天然而然,效率不會很高~
反思了一下,其實遞歸還能夠再簡短一點
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reversePrint(head *ListNode) []int {
if head == nil {
return []int{}
}
return append(reversePrint(head.Next), head.Val)
}複製代碼
結果以下:
想了一下,這樣不行啊,耗時這麼長,試試不用遞歸吧~
而後就想,若是我反轉鏈表呢,再生成數組返回,這樣也能夠實現吧?
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reversePrint(head *ListNode) []int {
if head == nil {
return nil
}
var newHead *ListNode
res := []int{}
for head != nil {
node := head.Next
head.Next = newHead
newHead = head
head = node
}
for newHead != nil {
res = append(res, newHead.Val)
newHead = newHead.Next
}
return res
}複製代碼
結果以下:
反轉鏈表再獲取數值,能夠是能夠,會不會有點多餘?還不如直接順序獲取值放到數組,再反轉結果呢~
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reversePrint(head *ListNode) []int {
if head == nil {
return nil
}
res := []int{}
for head != nil {
res = append(res, head.Val)
head = head.Next
}
for i, j := 0, len(res)-1; i < j; {
res[i], res[j] = res[j], res[i]
i++
j--
}
return res
}複製代碼
至此,結果有了很大的提高:
這個反轉數組仍是感受好奇怪,有沒有更好的方法呢?把先讀到的放最後,最後的在最前面,棧不就是這樣的數據結構嗎?
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
import "container/list"
func reversePrint(head *ListNode) []int {
if head == nil {
return nil
}
res := list.New()
for head != nil {
res.PushFront(head.Val)
head = head.Next
}
ret := []int{}
for e := res.Front(); e != nil; e = e.Next() {
ret = append(ret, e.Value.(int))
}
return ret
}複製代碼
三下五除二,搞定!來看當作果:
其實到棧,我覺得這題就這樣了,然而......
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reversePrint(head *ListNode) []int {
if head == nil {
return nil
}
count := 0
newHead := head
for head != nil {
count++
head = head.Next
}
res := make([]int, count)
i := 0
for newHead != nil {
res[count-i-1] = newHead.Val
i++
newHead = newHead.Next
}
return res
}複製代碼
臥槽!!!質的提高,既省去自動擴容的性能,也能提升處理速度:
歡迎關注公衆號:若魚治水,文章會首發在公衆號,也可備註加我備註進羣進技術交流羣~