LeetCode 61. 旋转链表(Rotate List)题解与思路详解

题目简介:旋转链表(Rotate List)

LeetCode原题链接(题目编号:61):https://leetcode.com/problems/rotate-list/

将链表向右旋转 k 个位置。

示例:

  • 输入:1->2->3->4->5, k = 2
  • 输出:4->5->1->2->3

  • 输入:0->1->2, k = 4
  • 输出:2->0->1

约束条件:

  • 链表长度 [0, 500]
  • 节点值 [-100, 100]
  • 0 <= k <= 2 * 10^9

我的解题思路与优化过程

初版思路

  1. 尝试引入 dummy 节点,让所有指针操作更统一(tail、head 切换更方便)。
  2. 设定两个指针 startend,同时遍历找到该断开重组的位置。
  3. 考虑让 end 向后走 n + 1 步后,与 start 一起走,直到 endNULL,这样 start 指向新头、end_prev 为新尾,重新接链。

但进一步思考发现:

  • 需要先遍历一遍链表来获得其实际长度 len,进而用于 k % len 去"化简"大旋转步数。
  • dummy 节点其实不是必须的,代码简化后逻辑会更清晰。
  • 只需考虑特殊情况:空链表、单节点、多余旋转(k % len == 0),直接返回不变。

正确且主流的官方解法

  1. 先遍历一遍得到长度 len
  2. k = k % len 化简实际旋转长度。
  3. 快慢指针找到新的断链位置。 也就是第 (len-k) 个节点为新尾,(len-k+1) 为新头。
  4. 断链重组。 新尾指向 None,原链表尾接上原头(成环再断开)。

时间复杂度为何仍然是 O(n) 而不是 O(2n):

  • 遍历两次都是 O(n),常数系数不影响大 O 记法。

dummy 节点其实可以不用

本题不涉及头部插入删除,所以直接操作 head 指针、处理 next 就够了,用 dummy 节点反而增加复杂度。

只要写清楚边界情况(空链表/单节点),后续断链按标准流程进行,不会有隐藏 bug。


面试官可能关心的问题

  1. 你有没有关注特殊情况的鲁棒性处理?
  2. 你明不明白 O(2n) 与 O(n) 没实质差异?
  3. dummy 节点的使用场景到底适不适合这题?
  4. 你能否说清,哪些链表题"必须 dummy"?哪些不用?

总结

  • 旋转链表最优解法是"两遍遍历 + 断链重组",不是只为了代码简洁,更是因为它符合单链表操作的本质 & 性能极限。
  • dummy 节点不是万能,使用要有场景;本题不用 dummy 更简明。
  • 不用计较多一遍遍历,这种做法就是最优解,并且是官方推荐路线。

如需代码,只需进一步细节化流程步骤即可。

(注:本回答特意不贴出代码,体现面试交流思路为主的风格)


相关链接:

相关推荐
wWYy.4 小时前
数组快排 链表归并
数据结构·链表
YuTaoShao5 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法一)排序+滑动窗口
算法·leetcode·排序算法
田野追逐星光6 小时前
STL容器list的模拟实现
开发语言·c++·list
TracyCoder1236 小时前
LeetCode Hot100(27/100)——94. 二叉树的中序遍历
算法·leetcode
草履虫建模13 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
VT.馒头18 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
不穿格子的程序员1 天前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法
VT.馒头1 天前
【力扣】2722. 根据 ID 合并两个数组
javascript·算法·leetcode·职场和发展·typescript
执着2591 天前
力扣hot100 - 108、将有序数组转换为二叉搜索树
算法·leetcode·职场和发展
兩尛1 天前
160. 相交链表/c++
数据结构·链表