想要精通算法和SQL的成长之路 - 旋转链表
- 前言
- 一. 旋转链表
前言
想要精通算法和SQL的成长之路 - 系列导航
一. 旋转链表
原题链接
由于k的大小可能超过链表长度,因此我们需要根据链表长度取模。那么我们首先需要去计算链表的长度是多少:
if (head == null) {
return head;
}
// 计算链表的长度
ListNode tmp = head;
int len = 0;
while (tmp != null) {
len++;
tmp = tmp.next;
}
// 取模
k = k % len;
然后,我们用双指针去完成剩余的步骤:
-
准备快慢两个指针,分别指向头结点。
-
fast
指针向后移动k
位。那次是fast
指针后的链表部分。就是需要迁移到链表头部的区域。
-
快慢指针同时向后移动,直到
fast
指针指向链表的结尾处
-
此时,
fast.next
应该指向head
(此时链表成环),新的头结点应该更细为slow.next
,更新完毕后,slow.next
断开(解除环)
代码如下:
ListNode slow = head, fast = head;
// 快指针先移动k位
for (int i = 0; i < k; i++) {
fast = fast.next;
}
// 快慢指针同时移动,直到fast到达链表末尾
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
// 末尾指向原Head,形成环
fast.next = head;
// 认定新的头结点
head = slow.next;
// 解除环状
slow.next = null;
最终完整代码如下:
public ListNode rotateRight(ListNode head, int k) {
if (head == null) {
return head;
}
// 计算链表的长度
ListNode tmp = head;
int len = 0;
while (tmp != null) {
len++;
tmp = tmp.next;
}
k = k % len;
ListNode slow = head, fast = head;
// 快指针先移动k位
for (int i = 0; i < k; i++) {
fast = fast.next;
}
// 快慢指针同时移动,直到fast到达链表末尾
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
// 末尾指向原Head,形成环
fast.next = head;
// 认定新的头结点
head = slow.next;
// 解除环状
slow.next = null;
// 返回新头结点
return head;
}