一、题目
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
示例 2:
输入:head = [0,1,2], k = 4
输出:[2,0,1]
提示:
- 链表中节点的数目在范围 [0, 500] 内
- -100 <= Node.val <= 100
- 0 <= k <= 2 * 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、分析及代码
1. 快慢指针
(1)思路
设计 2 个指针,快指针比慢指针多移动 k 个位置,则当快指针移到链表末尾时,慢指针移到原链表需断开(即新链表头节点)的位置。
因为题中所给 k 可能远大于链表节点数 n,通过等效,当 k > n 时只需移动 k % n 个位置。
(2)代码
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0)
return head;
ListNode node = head;//指针1
int len = 0;//链表长度
for (int i = 0; i < k; i++) {//向右移动
if (node.next != null)//范围小于链表长度,直接移动
node = node.next;
else {//范围大于链表长度,记录链表长度
node = head;
len = i + 1;
break;
}
}
if (len != 0) {//范围大于链表长度,直接移动 k % len
if (k % len == 0)
return head;
for (int i = k % len; i > 0; i--)
node = node.next;
}
ListNode node2 = head;//指针2,在指针1后k个位置
while (node.next != null) {
node = node.next;
node2 = node2.next;
}
ListNode newHead = node2.next;
node2.next = null;
node.next = head;//将原尾节点和头节点连接
return newHead;
}
}
(3)结果
执行用时 :0 ms,在所有 Java 提交中击败了 100.00% 的用户;
内存消耗 :37.9 MB,在所有 Java 提交中击败了 44.93% 的用户。
三、其他
还可直接遍历整个链表得到长度 n,并将链表首尾相连后在 n - k % n 处将原链表断开,虽然可能增加了一次遍历,但代码更简洁。