LeetCode61. 旋转链表

61. 旋转链表 ------ 三步成环法

这道题的核心在于:先连成环,再找断点,最后断开。


题目链接

题目简述

给定一个单链表和一个非负整数 k,将链表向右旋转 k 个位置。

例如:

  • 输入:1 → 2 → 3 → 4 → 5k = 2
  • 输出:4 → 5 → 1 → 2 → 3

解题思路

采用的"成环 + 找断点"的策略:

  1. 先成环:把链表的尾部指向头部,变成一个环形链表。
  2. 再找断点 :从头部开始走 n - k - 1 步(n 是链表长度),找到新的尾部。
  3. 最后断开 :把新尾部的 next 设为 nullptr,新头部就是它的 next

代码详解(配合示意图)

cpp 复制代码
ListNode* rotateRight(ListNode* head, int k) {
    if(head == nullptr) return nullptr;

    // 1. 找链表长度 n,并让 tem 指向最后一个节点
    ListNode* tem = head;
    int n = 1;  // 从1开始,因为至少要算上头节点
    while(tem->next != nullptr) {
        n++;
        tem = tem->next;
    }
    // 不能用下面的方法计算,这样最后扫描到的结点是空结点
		// int n = 0;
    // while(tem != nullptr)
    // {
    //     n++;
    //     tem = tem -> next;
    // }
    // 2. 连成环:让最后一个节点指向头节点
    tem->next = head;

    // 3. 计算实际需要移动的步数(取模避免越界)
    k = k % n;
    int x = 1;
    ListNode* p = head;

    // 4. 走 n - k -1步,找到新链表的尾部
    while(x <= n - k - 1) {
        x++;
        p = p->next;
    }

    // 5. 断开环,设置新的头尾
    head = p->next;  // 新的头是断点后的下一个节点
    p->next = nullptr;  // 断点处设为 nullptr

    return head;
}

图解过程

初始状态:

复制代码
head → 1 → 2 → 3 → 4 → 5 → nullptr

第一步:找长度和尾部

  • temhead 开始,走到 5
  • n = 5

第二步:成环

复制代码
5 → head → 1 → 2 → 3 → 4 → 5 (环形)

第三步:找断点

  • k = 2,所以 n - k - 1= 2
  • phead 出发,走 2 步:
    • 第1步:p = 2
    • 第2步:p = 3
  • 此时 p 指向 3,它是新链表的尾部。

第四步:断开环

  • head = p->next = 4

  • p->next = nullptr

  • 结果:

    4 → 5 → 1 → 2 → 3 → nullptr


关键点总结

  • 为什么 tem->next != nullptr

    因为我们想让 tem 最终停在最后一个节点 ,而不是 nullptr。如果写成 tem != nullptrtem 会走到 nullptr,那 tem->next 就炸了。

  • 为什么 n 从 1 开始?

    因为我们至少包含头节点。比如链表只有一个节点,n=1,循环不会执行,tem 还是头节点,没问题。

  • 为什么是 n - k - 1

    因为向右旋转 k 步,相当于把前 n - k 个节点移到后面。所以新尾部就是 是n - k 个节点本身

    比如 n=5, k=2,新尾部是第 3 个节点(索引从0开始),新头部是第 4 个节点。

  • 为什么 k = k % n

    如果 kn 大,比如 k=7, n=5,其实等价于 k=2,因为转一圈等于没转。


复杂度分析

  • 时间复杂度 :O(n)

    一次遍历找长度,一次遍历找断点,总共 2n,所以是 O(n)。

  • 空间复杂度 :O(1)

    只用了几个指针变量,没有额外空间。


小结

这道题用"成环法"非常优雅,避免了复杂的数组拷贝或多次遍历。配合你的手绘图,逻辑一目了然:

成环 → 找点 → 断开,三步搞定旋转链表。

画图真的很有帮助,尤其是链表这种结构,一眼就能看出指针怎么走、断在哪里。

相关推荐
被AI抢饭碗的人1 小时前
高并发内存池实现
开发语言·c++
眼眸流转2 小时前
LeetCode热题100(一)
算法·leetcode
渡过晚枫2 小时前
[第十六届蓝桥杯/java/算法]1.偏蓝
java·算法·蓝桥杯
.小小陈.2 小时前
C++进阶7:深入理解哈希表,从原理到 C++ 实践
开发语言·c++·学习·哈希算法
2501_940315262 小时前
【无标题】1302 层数最深叶子节点的和
java·数据结构·算法
isxhyeah2 小时前
python 数据结构 排序算法
数据结构·python·排序算法
invincible_Tang2 小时前
AcWing 796. 子矩阵的和 _
数据结构·算法
米粒12 小时前
力扣算法刷题 Day 8
算法·leetcode·职场和发展
keep intensify2 小时前
康复训练 2
c++