返回

算法趣谈:25. K 个一组翻转链表,智者同行,趣味相生

前端

在算法与编程的世界里,我们总能在前人的基础上不断前行,LeetCode 便是一个分享与学习的宝藏。今天,我们来细细品味 25. K 个一组翻转链表 这道题,看看如何将链表每 K 个节点一组进行翻转。

首先,让我们来理清题目的要求:给定一个链表,我们要每 K 个节点一组进行翻转。这其中的难点在于,如何将链表中的节点分组,并进行翻转。

两种常见解法,殊途同归的妙招

为了解决这个问题,我们可以采用两种常见的解法:递归法和迭代法。

递归法:

递归法以一种自顶向下的方式将链表翻转。具体步骤如下:

  1. 将链表的第一个 K 个节点翻转。
  2. 将剩下的链表继续以同样的方式进行翻转。
  3. 将翻转后的链表连接起来。

迭代法:

迭代法以一种自底向上的方式将链表翻转。具体步骤如下:

  1. 使用两个指针将链表分成 K 个节点一组。
  2. 将每个 K 个节点一组的链表翻转。
  3. 将翻转后的链表连接起来。

代码示例:

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        # 递归法

        if not head or k == 1:
            return head

        # 翻转前 K 个节点
        curr = head
        prev = None
        for _ in range(k):
            next_node = curr.next
            curr.next = prev
            prev = curr
            curr = next_node

        # 翻转剩下的链表
        head.next = self.reverseKGroup(curr, k)

        # 返回翻转后的链表
        return prev


    def reverseKGroup_iterative(self, head: ListNode, k: int) -> ListNode:
        # 迭代法

        dummy = ListNode(0)
        dummy.next = head

        prev = dummy
        curr = head

        while curr:
            # 将链表分成 K 个节点一组
            group_start = curr
            group_end = curr

            for _ in range(k - 1):
                if group_end.next:
                    group_end = group_end.next
                else:
                    break

            # 翻转 K 个节点一组的链表
            next_group_start = group_end.next

            prev.next = self.reverse_list(group_start, group_end)

            # 连接翻转后的链表
            group_start.next = next_group_start

            # 更新 prev 和 curr 指针
            prev = group_end
            curr = next_group_start

        # 返回翻转后的链表
        return dummy.next


    def reverse_list(self, start: ListNode, end: ListNode) -> ListNode:
        prev = None
        curr = start

        while curr != end:
            next_node = curr.next
            curr.next = prev
            prev = curr
            curr = next_node

        return prev

结语

  1. K 个一组翻转链表 这道题看似复杂,但只要我们能够熟练掌握递归或迭代的方法,就能轻松解决。同时,这也是一个很好的算法与编程练习题,希望你能从中有所收获。

我们坚信,只要坚持不懈地学习和实践,算法与编程的世界将会为你展现出无穷的魅力。加油,算法爱好者们!