Skip to content

图书整理 I

书店店员有一张链表形式的书单,每个节点代表一本书,节点中的值表示书的编号。为更方便整理书架,店员需要将书单倒过来排列,就可以从最后一本书开始整理,逐一将书放回到书架上。请倒序返回这个书单链表。

示例 1:

bash
输入:head = [3,6,4,1]

输出:[1,4,6,3]

方法一:递归

利用递归,先递推至链表末端;回溯时,依次将节点值加入列表,即可实现链表值的倒序输出。

  • 终止条件: 当 head == None 时,代表越过了链表尾节点,则返回空列表;
  • 递推工作: 访问下一节点 head.next ;
go
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */

func reverseBookList(head *ListNode) []int {
    var data []int
    recur(head, &data)
    return data
}

func recur(head *ListNode, data *[]int) {
    if head == nil {
      return
    }
    recur(head.Next, data)
    *data = append(*data, head.Val) 
}

方法二:辅助栈法

  • 入栈: 遍历链表,将各节点值 push 入栈。
  • 出栈: 将各节点值 pop 出栈,存储于数组并返回。
go
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */

func reverseBookList(head *ListNode) []int {
    stack := list.New()
    for head != nil {
        stack.PushBack(head.Val)
        head = head.Next
    }
    data := make([]int, 0)
    for stack.Len() > 0 {
        data = append(data, stack.Back().Value.(int))
        stack.Remove(stack.Back())
    }
    return data
}

方法三:反转链表

先将原链表反转,然后再遍历反转后的链表,将值依次存入数组中。

go
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */

func reverseBookList(head *ListNode) []int {
    var data []int
	reverseHead := reverseList(head)
	for reverseHead != nil {
		data = append(data, reverseHead.Val)
		reverseHead = reverseHead.Next
	}
	return data
}

func reverseList(head *ListNode) *ListNode {
	var pre *ListNode
	for head != nil {
		next := head.Next
		head.Next = pre
		pre = head
		head = next
	}
	return pre
}