返回

亲身经验: LeetCode学算法,'24. 反转链表'的多种解题方式

前端

在算法学习的道路上,LeetCode无疑是一个璀璨的明星,它以其海量的题目、清晰的分类和详尽的解析,吸引了无数热爱算法的朋友们。而在剑指offer专题中,“24. 反转链表”这一经典问题更是备受瞩目。今天,就让我们一起探讨如何高效解决这个问题,并深入理解其背后的算法逻辑。

一、问题概述

反转链表,即将一个链表中的节点顺序颠倒,使其成为一个新的链表。这个问题看似简单,实则考察了我们对链表操作的理解和算法设计的思维。

二、迭代法:逐步反转链表

迭代法是最直观、最常用的解决方法。它的基本思想是通过循环,逐步改变链表的指向,最终实现链表的反转。

步骤详解

  1. 初始化变量

    • cur:当前节点,初始为链表头节点。
    • prev:当前节点的前一个节点,初始为None
    • next:当前节点的下一个节点,用于临时保存下一个节点的指向。
  2. 遍历链表

    • 在每次循环中,先保存当前节点的下一个节点(next = cur.next)。
    • 然后将当前节点的next指针指向prev,实现局部反转。
    • 接着将prev更新为当前节点(prev = cur)。
    • 最后将当前节点更新为下一个节点(cur = next)。
  3. 结束条件

    • curNone时,遍历结束,此时prev指向新的头节点。

代码示例

以下是Python语言的实现代码:

def reverse_list(head):
    cur = head
    prev = None
    while cur:
        next = cur.next  # 保存下一个节点
        cur.next = prev  # 反转当前节点的指向
        prev = cur       # 移动prev到当前节点
        cur = next       # 移动cur到下一个节点
    return prev  # prev现在指向新的头节点

三、递归法:分解问题,逐个解决

递归法是一种更优雅的解决方法,它通过将问题分解成更小的子问题来解决整个问题。

步骤详解

  1. 基本情况

    • 如果链表为空或只有一个节点,直接返回该链表,因为不需要反转。
  2. 递归情况

    • 否则,先递归地反转从当前节点的下一个节点开始的子链表。
    • 然后将当前节点的next指针指向递归返回的新头节点(即原链表的尾节点)。
    • 最后将当前节点的next置为None,断开与原链表的连接。

代码示例

以下是Python语言的实现代码:

def reverse_list(head):
    if not head or not head.next:
        return head
    next = reverse_list(head.next)  # 递归反转子链表
    head.next.next = head  # 反转当前节点与下一个节点的连接
    head.next = None  # 断开与原链表的连接
    return next  # 返回新的头节点

四、选择适合你的解题思路

对于“24. 反转链表”这个问题,迭代法和递归法都是有效的解决方案。迭代法更直观易懂,适用于大多数情况;而递归法则更简洁优雅,但需要注意递归深度的问题。你可以根据自己的理解和喜好选择合适的方法。

五、结语

通过本文的介绍,相信你对“24. 反转链表”有了更深入的了解,并掌握了两种不同的解题方法。在算法学习的道路上,不断尝试和探索是提高自己能力的关键。希望你在LeetCode上继续挑战自我,解决更多经典问题!