旋转链表
题目描述
- 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
题解(java)
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null)
return head;
ListNode fast = head, slow = head;
//链表的长度
int len = 1;
//统计链表的长度,顺便找到链表的尾结点
while (fast.next != null) {
len++;
fast = fast.next;
}
//首尾相连,先构成环
fast.next = head;
//慢指针移动的步数
int step = len - k % len;
//移动步数,这里大于1实际上是少移了一步
while (step-- > 1) {
slow = slow.next;
}
//temp就是需要返回的结点
ListNode temp = slow.next;
//因为链表是环形的,slow就相当于尾结点了,
//直接让他的next等于空
slow.next = null;
return temp;
}
}
图示
详解(双指针)
-
如上图所示,简单来说,此题的目的就是将 K 个尾节点旋转到头结点去,本体采用双指针的解法,fast指针从头节点遍历到尾节点,得到链表的长度n,然后与头结点相连形成环路。
-
形成环路后,我们只需要找到合适的位置断开两节点,便可得到新的链表,而怎么判断断开链表的位置就是此题的关键。
-
我们已知要移动 k 步,链表的长度为 n.,那么slow指针移动n - k就是我们要找的头结点(这里建议看图更加直观),但是!题中并没有指出n > k,所以考虑到n < k的情况,我们对 k 取余,即 k%n.所以 slow移动 (n - k%n) 就是我们要找的头结点。
-
因为我们要返回的是头结点,slow移动到的位置应为头结点的前一个节点。先找到slow.next,再使slow.next = null,断开节点。最后返回新得到链表
Tips
- 注意:首先要判断该链表是否为空链表或只有一个节点的链表,如果是,返回头结点即可。
- 注意:在移动慢指针的时候,while (step-- > 1)要少移动一步。
- 注意:最后在断开链表之前,要先找到temp,否则新的头结点将无法找到。
难点
找到断开链表的位置
声明
- 原作者:E.L.E
- <著作权归作者所有,商业转载请获得原作者允许,非商业转载请注明来处,欢迎大家评论>