LeetCode 206. 反转链表 & 剑指offer 面试题24. 反转链表(易)
链表的基础操作,递归、循环两种形式都必须要会手写。
链表
题目
反转一个单链表。
示例: 1
2输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
测试用例
输入的链表头指针是 nullptr
。 输入的链表只有一个节点。 输入的链表有多个节点。
直觉
1、递归
递归是从后往前递归的,假设后面一部分已经反转好,现在要反转前面一部分。递归的最后一层就是 tail
,tail
被逐层 return
。
假设列表为:
\[ n_{1}\rightarrow ... \rightarrow n_{k-1} \rightarrow n_{k} \rightarrow n_{k+1} \rightarrow ... \rightarrow n_{m} \rightarrow \mbox{None} \]
若从节点 \(n_{k+1}\) 到 \(n_{m}\) 已经被反转,而我们正处于 \(n_{k}\)。
\[ n_{1}\rightarrow ... \rightarrow n_{k-1} \rightarrow n_{k} \rightarrow n_{k+1} \leftarrow ... \leftarrow n_{m} \]
我们希望 \(n_{k+1}\)的下一个节点指向 \(n_{k}\),所以 \(n_{k}.next.next = n_{k}\)。
要小心的是 \(n_{1}\) 的下一个必须指向 None
。如果你忽略了这一点,你的链表中可能会产生循环。如果使用大小为 2 的链表测试代码,则可能会捕获此错误。
2、循环
更新 pre_p
、p
、next_p
四个指针,设置哑节点,每次把要反转的 p
节点指向 pre_p
,先利用 p
更新 pre_p
,再利用 next_p
更新 p
。
1 |
|
关键的7行代码
1 |
|
特别注意 head.next = None
代码
递归
1 |
|
迭代
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!