这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战
leetcode 旋转链表
给你一个链表的头节点 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]
解题:正常的来讲,如果要移动链表,那就要将链表的每一个节点都往后移动,最后面的节点就移动到链表头部,这种操作比较复杂,所以可以考虑有没有别的办法。节点的移动就是改变next节点的指向,那如果先将链表链接为一个闭环,那么如果要移动k个位置,那只需要将原链表头结点位置移动k个位置到达的节点,然后从这里断开闭环,这就是一个移动后的链表了。假如链表的节点数即链表长度为len,len的范围为0 <= len <= 500,然后如果要移动k个位置,k的范围为0 <= k <= 2 * (10的9次方),那么k是有可能大于等于len的,但是我们可以发现如果是移动k个位置等于len的话,那么链表往后移动len个位置就又回到了原链表的状态,所以其实当k等于len的整数倍就不用移动,就是我们只需移动k % len个位置就可。具体的可以先判断,如果链表不足两个节点或者k为0可以直接返回原链表;然后就遍历链表获取链表节点数,同时找到最后一个节点,判断如果k为链表长度的倍数,那就算真的移动了也是回到原来链表的状态,所以可以直接返回原链表,否则将最后一个节点与头结点相连来形成闭环链表,然后遍历闭环链表到达k位置,将闭环链表从此断开,就形成一个移动k位置后的链表了。
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (k == 0 || head == null || head.next == null) {
return head;
}
int len = 1;
ListNode tail = head;
while (tail.next != null) {
tail = tail.next;
len++;
}
int add = len - k % len;
if (add == len) {
return head;
}
tail.next = head;
while (0 < add--) {
tail = tail.next;
}
ListNode ret = tail.next;
tail.next = null;
return ret;
}
}