题目描述
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
做过旋转数组的那个题之后,这样的旋转方式需要翻转三次,想想就复杂。
下面说一种较为简单的方法,旋转之后链表的头节点以及尾节点发生了变化。因此需要找到旋转之后的头节点和尾节点即可。题目要求是将后边的k个节点移动到前面,因此新的尾节点就是在len-k-1 处,新的头节点在len-k处,旧的尾节点在计算链表长度时得出,千万不要遍历到链表末尾,不然到最后在旧的链表尾处链接新的那部分节点时 oldTail==nullptr 无法进行next操作,指针也就越界了。如果链表的长度小于等于 k 的长度,需要对 K 取模。如果取模之后等于0,那么相当于没有旋转,
边界条件 :k =0 或者 head ==nullptr 需要特判一下。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(!head || !k ) return head;
int len=1;
ListNode* newTail=head,*oldTail=head,*newHead=head;
while(oldTail->next)
{
len++;
oldTail=oldTail->next;
}
k = k%len;
if(!k) return head;
for(int i=0;i<len-k-1;i++) newTail=newTail->next;
for(int i=0;i<len-k;i++) newHead=newHead->next;
newTail->next=nullptr;
oldTail->next=head;
return newHead;
}
};