本文已参加 新人礼创作礼 活动,一起开启掘金创作之旅
题目描述
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
样例
blablabla
输入: head = [1,2,3,4,5], k = 2
输出: [4,5,1,2,3]
输入: head = [0,1,2], k = 4
输出: [2,0,1]
算法1
(快慢指针)
- 由于 k 可能会大于链表总结点数,超过的部分是无意义的,故可以先求出链表的结点总数 n,然后 k 对 n 取余,k %= n
- 需要完成链表的旋转,需要找到链表的两个结点,倒数第
k + 1个结点,倒数第k - 1个结点,如图:
- 定义两个指针,分别指向
head,第一个指针 p 先向下移动k步, 然后两个指针 p, q 同时向后移动,直到p 的下一个节点为 null,此时的结点 q 就指向了 倒数 k + 1的位置,结点 p 指向了倒数第 k - 1 个位置,下面就可以进行旋转链表了。 - 首先 p 的下一个结点应该指向 head, 此时 head 变为 q 的下一个结点,最后 q 的下一个结点变为 null;
- 返回 head
ps: 当链表为空时,结点数为 0,此时取余会出现错误,需要进行特判,当链表为空时,直接放回 null。
Java 代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// 特判,
if (head == null) return null;
// 快指针
ListNode p = head;
// 慢指针
ListNode q = head;
int n = 0;
// 求结点总数
while(p != null) {
p = p.next;
n ++;
}
k %= n;
p = head;
while((k--) != 0) {
p = p.next;
}
while(p.next != null) {
p = p.next;
q = q.next;
}
// 旋转链表
p.next = head;
head = q.next;
q.next = null;
// 返回结果
return head;
}
}