「这是我参与11月更文挑战的第 1 天,活动详情查看:2021最后一次更文挑战」
反转链表
题目来源:LeetCode-206. 反转链表
题目描述
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表
示例
示例 1
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2
输入:head = [1,2]
输出:[2,1]
示例 3
输入:head = []
输出:[]
提示:
- 链表中节点的数目范围是
[0, 5000]
5000 <= Node.val <= 5000
解题
解法一:就地反转
思路
就地反转法,找一个空的节点来充当新的头结点(类似哨兵),然后遍历待反转的链表中每一个结点,将每一次遍历到的结点都插入到新的头结点后边,过程如下:
最主要的地方在于每次将遍历到的结点,插入到哨兵结点的后边
代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil{
return head
}
newHead := &ListNode{}
newHead.Next = head
prevNode := newHead.Next
currentNode := prevNode.Next
for currentNode != nil {
prevNode.Next = currentNode.Next
currentNode.Next = newHead.Next
newHead.Next = currentNode
currentNode = prevNode.Next
}
head = newHead.Next
return head
}
执行结果
解法二:头插法
思路
这种方法比较简单,就是创建一个新的链表,将待反转的链表的每一个节点,通过头插法的方式,插入到新的链表中
代码
func (list *List) ReverseListHead() {
if list.headNode == nil {
fmt.Println("链表为空")
return
}
newList := &List{}
currentNode := list.headNode
nextNode := currentNode.Next
for currentNode!=nil {
if newList.headNode == nil {
newList.headNode = currentNode
newList.headNode.Next = nil
currentNode = nextNode
continue
}
nextNode = currentNode.Next
currentNode.Next = newList.headNode
newList.headNode = currentNode
currentNode = nextNode
}
fmt.Println("反转后")
newList.Traverse()
}