📌  相关文章
📜  将链表的子表从位置 M 到 N 向右旋转 K 位(1)

📅  最后修改于: 2023-12-03 14:53:55.460000             🧑  作者: Mango

将链表的子表从位置 M 到 N 向右旋转 K 位

问题描述

给定一个单链表和两个整数 m 和 n。从位置 m 开始将链表的子表反转,到第 n 个节点结束。要求只使用一趟扫描完成链表的旋转,并且使用常数级别的空间复杂度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4, k = 1
输出: 1->4->2->3->5->NULL
思路

首先遍历链表,找到第 m - 1 个节点,将其作为 pre,m 节点作为 head,n 节点作为 tail,将 pre.next 指向 Null,将 head 到 tail 之间的节点反转。

接下来,将 pre 指向反转后的头节点,将 tail 指向反转后的尾节点,将 pre.next 指向 head,将 tail.next 指向 next,返回链表头即可。

如果 m = 1,则 pre 为 Null,直接将 tail 节点赋值给 head 即可。

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

class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int, k: int) -> ListNode:
        # 边界情况处理
        if not head or not head.next or m == n:
            return head

        # 新增一个虚拟节点指向 head,以方便处理 m = 1 的情况
        dummy = ListNode(-1)
        dummy.next = head

        # 找到第 m - 1 个节点 pre,将其作为 pre,m 节点作为 head,n 节点作为 tail
        pre = dummy
        for i in range(m - 1):
            pre = pre.next
        head = pre.next
        tail = head
        for i in range(n - m):
            tail = tail.next

        # 反转 head 到 tail 之间的节点
        p, q = head, head.next
        for i in range(n - m):
            tmp = q.next
            q.next = p
            p, q = q, tmp
        head.next = q
        tail.next = None

        # 将 pre 指向反转后的头节点,将 tail 指向反转后的尾节点
        # 如果 m = 1,则 pre 为 null,直接将 tail 节点赋值给 head
        if m == 1:
            dummy.next = tail
        else:
            pre.next = tail

        # 返回链表头
        return dummy.next
复杂度分析
  • 时间复杂度:$O(n)$,一趟扫描。
  • 空间复杂度:$O(1)$,常数级别的空间复杂度。