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 更简明。
  • 不用计较多一遍遍历,这种做法就是最优解,并且是官方推荐路线。

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

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


相关链接:

相关推荐
DanyHope12 分钟前
《LeetCode 49. 字母异位词分组:哈希表 + 排序 全解析》
算法·leetcode·哈希算法·散列表
iAkuya15 分钟前
(leetcode) 力扣100 15轮转数组(环状替代)
数据结构·算法·leetcode
努力学算法的蒟蒻25 分钟前
day38(12.19)——leetcode面试经典150
算法·leetcode·面试
iAkuya42 分钟前
(leetcode)力扣100 17缺失的第一个正数(哈希)
算法·leetcode·哈希算法
sin_hielo1 小时前
leetcode 2092(排序+bfs)
算法·leetcode·宽度优先
无限进步_3 小时前
【C语言】队列(Queue)数据结构的实现与分析
c语言·开发语言·数据结构·c++·算法·链表·visual studio
YoungHong19924 小时前
面试经典150题[074]:填充每个节点的下一个右侧节点指针 II(LeetCode 117)
leetcode·面试·职场和发展
DanyHope4 小时前
LeetCode 128. 最长连续序列:O (n) 时间的哈希集合 + 剪枝解法全解析
前端·leetcode·哈希算法·剪枝
元亓亓亓4 小时前
LeetCode热题100--763. 划分字母区间--中等
算法·leetcode·职场和发展
Dream it possible!4 小时前
LeetCode 面试经典 150_回溯_全排列(100_46_C++_中等)
c++·leetcode·面试·回溯