问题描述
来源: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
问题分析
方法一:递归
递归解放主要是理解递归顺序
假设链表为
1——>2——>3——>4——>5
递归是到最后以后开始返回,因此我们可以倒着来看结果
5——>4,4——>3,3——>2,2——>1
既是: 第n个指向n-1个,例如5指向4,就可以写成
4.next.next = 4// 相当于 5.next = 4#反转后的结构就是1——>2——>3——>nil,4<——>5# 4和5成环了,因此还需要解环4.next = nil
具体见代码
方法二:迭代
例如:
1——>2——>3——>4——>5
实现1——》nil, 2——》1
不妨给三个变量
cur: 记录当前节点
fast:记录下一个节点
mid:中间缓存
开始时:cur=1,fast=2, 则进行如下操作就可以实现 2——>1
// 提前获取一下下一个值,防止操作后找不到后续节点
mid=fast.next // mid = 3
fast.next = cur // 2——>1
cur = fast // cur = 2
fast = mid // fast 继续指向下一个值,fast = 3
// 第二次迭代就可以得到
mid=4
3——>2——>1
cur =3
fast = 4
因此可以得到下列代码
代码实现
goalng
递归
func reverse(head *ListNode) *ListNode {
// head处理本身就是空的情况, head.Next 处理到结尾了
if head == nil || head.Next == nil {
return head
}
newHead := reverse(head.Next)
// 末尾成环, 例如 1,2,3
// head.Next.Next 就是3.Next
// 这时的head是2
// 1——>2<->3
head.Next.Next = head
// 去环 1——2<——3
head.Next = nil
return newHead
}
迭代
func reversal(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
// 1——>2——>3
fast := head.Next // fast=2
head.Next = nil // 把头部置空,防止成环,1——>nil
var mid *ListNode
for fast != nil {
mid = fast.Next // mid= 3
fast.Next = head // 1<——2 3
head = fast // 把反转后的头节点记住
fast = mid //
}
return head
}