在问 · 算法题解

206. 反转链表

简单链表迭代(三指针)力扣原题 ↗

题目描述

输入单链表的头节点 head。把链表的方向整个倒过来,返回新的头节点。空链表返回 null。

链表以数组形式表示,例如 [1,2,3]。

示例 1
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

解释:反转后节点顺序为 5、4、3、2、1。

示例 2
输入:head = [1,2]
输出:[2,1]

解释:两个节点交换了先后。

示例 3
输入:head = []
输出:[]

解释:空链表反转后仍为空。

数据范围

  • 节点数在 [0, 5000] 范围内。
  • -5000 <= Node.val <= 5000

进阶:迭代和递归都能实现反转,你能分别写出两种做法吗?

解题思路:迭代(三指针)

迭代维护 prev 和 cur。先保存 cur.next,再把 cur.next 指向 prev,最后同步前进两个指针。

为什么正确

每轮结束时,prev 指向已反转的前缀,cur 指向尚未处理的后缀。

复杂度分析

时间 O(n),空间 O(1)。

易错点

修改 next 前必须先保存后继节点,否则剩余链表会丢失。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def reverseList(self, head):
        prev = None
        cur = head
        while cur:
            nxt = cur.next
            cur.next = prev
            prev = cur
            cur = nxt
        return prev

载入编辑器,自己跑一遍 →

其他解法

迭代从前往后逐个改变指针方向,空间 O(1);递归先一直走到链表末尾,在返回时从后往前改变指针,需要 O(n) 栈空间。

解法 2:递归 时间 O(n),空间 O(n)

先递归反转 head.next 开始的链表,得到新的头结点 newHead。此时 head.next 是反转后链表的尾结点,令 head.next.next = head,把 head 接到尾部,再把 head.next 设为空。空链表或只有一个结点时直接返回 head。

体现了“假设子问题已解决”的递归思想,代码简洁。需要 O(n) 递归栈,head.next.next = head 这一步不太好理解,需要画图。

from typing import Optional

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if head is None or head.next is None:
            return head
        new_head = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return new_head

链表 专题的其他题目

查看 链表 全部题目 →