返回

链表反转:从简单刷起~ 206

前端

前言

链表是数据结构中的重要组成部分,其在各种应用场景中发挥着至关重要的作用。链表反转是链表操作中一项常见的任务,熟练掌握这一技巧将大大提升你的编码能力。本文将从最简单的反转单链表入手,循序渐进,深入探讨反转链表的各种方法和技巧,最终助你成为链表操作的高手。

从零开始:单链表反转

单链表反转是指将链表中每个节点的指针方向反转,使链表呈现出从尾到头的顺序。最朴素的思路是使用迭代法,具体步骤如下:

  1. 定义两个指针,一个指向当前节点,另一个指向其前一个节点。
  2. 将当前节点的指针方向指向其前一个节点。
  3. 将前一个节点指针指向当前节点。
  4. 将当前节点指针移动到其后一个节点。
  5. 重复步骤2-4,直到遍历完整个链表。

使用这种方法可以有效地反转链表,时间复杂度为 O(n),其中 n 为链表长度。

进阶:递归反转链表

递归是一种解决问题的强大技巧,它也能用于反转链表。递归的思路是将链表分为两个部分:当前节点和剩余部分。具体步骤如下:

  1. 如果当前节点为最后一个节点,则直接返回。
  2. 反转剩余部分的链表。
  3. 将当前节点的指针方向指向其前一个节点。
  4. 将前一个节点指针指向当前节点。

这种方法的时间复杂度同样为 O(n),但它更简洁,更容易理解和记忆。

拓展:反转部分链表

在某些情况下,我们可能需要反转链表的特定部分。例如,将第 m 个节点到第 n 个节点之间的部分反转。此时,可以结合迭代和递归两种方法来实现。具体步骤如下:

  1. 使用迭代法找到第 m 个节点。
  2. 使用递归法反转从第 m 个节点到第 n 个节点之间的部分链表。
  3. 将反转后的部分链表与剩余部分重新连接。

这种方法的时间复杂度为 O(n),其中 n 为链表长度。

实战演练:LeetCode 206

LeetCode 206 题要求反转一个单链表。我们可以直接使用上面介绍的迭代法或递归法来解决。

代码示例:

# 迭代法反转链表
def reverse_list_iterative(head):
    prev = None
    curr = head

    while curr:
        temp = curr.next
        curr.next = prev
        prev = curr
        curr = temp

    return prev

# 递归法反转链表
def reverse_list_recursive(head):
    if not head or not head.next:
        return head

    p = reverse_list_recursive(head.next)
    head.next.next = head
    head.next = None

    return p

总结

链表反转看似简单,但其中蕴含着巧妙的技巧和算法思想。掌握链表反转不仅能提升你的编码能力,还能加深你对链表数据结构的理解。通过不断练习和探索,你一定能成为链表操作的高手。