题目:61. 旋转链表
解题思路
使用链表操作,时间复杂度为 O(n)。 核心逻辑是将链表尾部连接到头部形成环,然后找到新的断开点。具体步骤如下:
- 统计链表节点总数 n。
- 计算实际需要移动的步数 k = k % n。
- 若 k 为 0 则直接返回原头结点。
- 将尾节点指向头节点。
- 从头节点向后移动 n - k 步,找到新的尾节点。
- 记录新头节点(新尾节点的下一个),断开新尾节点与旧头节点的连接。
C++ 实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if (head == nullptr || head->next == nullptr || k == 0) return head;
int n = 1;
ListNode* cur = head;
// 统计完链表的节点数
while (cur->next != nullptr) {
n++;
cur = cur->next;
}
// 变化后的链表 = 右部分 + 左部分
// ans 就是左部分的数量
int ans = n - k % n;
// 将最后一个连到第一个节点
cur->next = head;
// 开始找左部分的最后一个点(即新的尾节点)
while (ans--) {
cur = cur->next;
}
// tmp 就是右部分的第一个节点(即新的头节点)
ListNode* tmp = cur->next;
cur->next = nullptr;
return tmp;
}
};
Java 实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
{
ListNode {
(head == || head.next == || k == ) head;
;
head;
(cur.next != ) {
n++;
cur = cur.next;
}
n - k % n;
cur.next = head;
(ans > ) {
ans--;
cur = cur.next;
}
cur.next;
cur.next = ;
tmp;
}
}

