返回

LeetCode 206: 链表反转 - 通俗易懂的递归与迭代解法

前端

众所周知,链表是一种基本的数据结构,它以其出色的时间效率而著称。而反转链表是一个常见的操作,即以相反的顺序重新排列链表中的节点。

这篇文章将深入探究 LeetCode 上广受欢迎的 206 号问题——链表反转,并为您提供两种通俗易懂的解法:递归和迭代。

递归解法:

对于初学者来说,递归解法可能更易于理解。它的基本思想是将链表看作一连串的节点,并将其分解为更小的子问题。

假设我们有一个链表:

head -> n1 -> n2 -> n3 -> null

递归解法的过程如下:

  1. 首先,我们定义一个基线情况:当链表为空(head 为 null)时,直接返回 null。
  2. 然后,我们通过调用递归函数反转链表的剩余部分:reversedSublist = reverseList(head.next)
  3. 最后,我们将当前节点 n1 指向反转后的子链表 reversedSublist,并将反转后的子链表返回作为新链表的头节点。
def reverseListRecursive(head):
  if head is None:
    return None

  reversedSublist = reverseListRecursive(head.next)
  head.next.next = head
  head.next = None

  return reversedSublist

迭代解法:

与递归解法不同,迭代解法使用显式的循环来反转链表。它维护三个指针:

  • prev:指向反转链表中的前一个节点
  • cur:指向当前要反转的节点
  • next:指向当前节点的下一个节点

迭代过程如下:

  1. 初始化 prev 为 null,cur 为 head,next 为 head.next。
  2. 在 while 循环中,更新 next 为 cur.next,将 cur.next 指向 prev,然后将 prev 更新为 cur,最后将 cur 更新为 next。
  3. 循环结束后,返回 prev 作为反转后的链表的头节点。
def reverseListIterative(head):
  prev = None
  cur = head

  while cur is not None:
    next = cur.next
    cur.next = prev
    prev = cur
    cur = next

  return prev

比较:

递归和迭代解法在效率和易用性方面各有优劣:

  • 效率: 递归解法在某些情况下可能比迭代解法稍慢,因为每次递归调用都会消耗额外的栈空间。
  • 易用性: 对于初学者来说,递归解法可能更易于理解和实现,而迭代解法需要更多的指针管理。

总结:

无论您选择哪种解法,LeetCode 206 题都是一个绝佳的机会,可以练习您的数据结构和算法技能。通过理解递归和迭代的原理,您将为解决更复杂的数据结构问题做好准备。