题目:给你一个链表的头节点head,旋转链表,将链表每个节点向右移动k个位置。
示例:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
算法:将所要旋转的链表看成一个闭环,移动k个位置相当于旋转k次改变了头结点。(这里可以将闭环看作一个钟表的旋转,头结点看作12点整)
1.将链表构成一个环 —>首尾相连,即尾节点指向头结点
2.找到旋转后的尾节点 (正数第n-k%n) —>因为可能k≥n,则需要k%n 特别提醒:如果k是n的整数倍,则新链表与原链表相同,不需要旋转
3.更改旋转后新的头结点,并进行切割环(断开首尾连接)
//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(!head || !head->next || k==0) return head;
int n=1;//统计结点个数n
ListNode* p=head;
while(p->next)//找到尾节点并统计结点个数
{
p=p->next;
n++;
}
int tail=n-k%n;
if(tail==n) return head;//k如果是n的整数倍,旋转后链表不变(注意:应该先判断k,再进行闭环处理,如若k是n的整数倍,则不需要闭环处理,直接返回原链表)
//构成环——>首尾结点相连
p->next=head;
//找到旋转后,新的尾节点
while(tail--)
{
p=p->next;
}
//更改旋转后新的头结点,并进行切割环(断开首尾连接)
head=p->next;
p->next=nullptr;