leetcode 61. 旋转链表
注意:首先一定要求出链表的长度 len,和题目给定的 k 值进行比较;如果 k > len,就要考虑取模 k=k % len; 保证 k < len;
当链表长度小于 k 时,情况如下图所示;
解题思路:使用快慢指针 fast, slow;让快指针先走 k 步,然后快慢指针一起走;这样当快指针来到链表结尾时,保证慢指针slow指向倒数第k个节点,即 slow.next 即是第 k个节点;然后想办法拼接 第 k 个节点之后的链表,和第k个节点之前的链表结构,得到目标链表,返回即可;
// 假设给定链表head 为 1-->2-->3-->4-->5
public static ListNode rotateKthListNode(ListNode head, int k) {
// 如果 链表为 null,或者 k==0 直接返回head即可
if (head == null || k == 0) {
return head;
}
// 记录链表长度
int len = 0;
// 使用temp作为中间节点遍历链表
ListNode temp = head;
while (temp != null) {
len++;
temp = temp.next;
}
// 如果 k%len == 0; 说明链表移动k位后还是会回到原来的链表结构,直接返回head即可;
if (k % len == 0) {
return head;
}
// 使用快慢指针
ListNode fast = head;
ListNode slow = head;
// 让快指针先走 k 步;保证 fast指针来到链表的最后位置时,slow.next指向第 k 个节点
while ((k % len) > 0) {
fast = fast.next;
k--;
}
// 快慢指针一起走,直到fast来到链表结尾位置;
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
// res为返回的链表 此时的res链表结构为 4-->5(fast)-->null
ListNode res = slow.next;
// 此时让 slow.next指向null, 这样原来的head链表结构变成 1-->2-->3-->null
slow.next = null;
// 让fast指针指向原来的head; 使得 res链表结构变为 4-->5-->1-->2-->3-->null;
fast.next = head;
return res;
}
画图来解释返回前的最后三步;
问题得以解决!!!