链接:https://leetcode-cn.com/problems/rotate-list
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
这道题其实就是将后k个节点放到前面来,但是有可能给的k值会大于链表长度n,所以先求模保证k一定是小于n的。然后需要两个指针分别指向倒数第一个结点和倒数第k+1个结点,方法和之前一样,先让first指针向前走k步,再让first指针和second指针同时走,直到first指针指向倒数第一个结点,此时的second指针指向倒数第k+1个结点。
然后开始移动这k个结点,将这k个结点看作一个整体进行移动,首先将first指针指向原头节点,再令头节点为second指针指向的下一个结点,最后让second指针指向空。顺序一定要对,否则会报错。
这道题虽然头节点变了,但是并没有删除等操作,所以不用设置虚拟结点。
c++代码如下:
1 class Solution { 2 public: 3 ListNode* rotateRight(ListNode* head, int k) { 4 if(!head) return NULL; 5 int n = 0; 6 for(auto p = head; p; p = p->next){ 7 n++; 8 } 9 k %= n; 10 auto first = head, second = head; 11 while(k--){ 12 first = first -> next; 13 } 14 while(first->next){ 15 first = first->next; 16 second = second-> next; 17 } 18 first->next = head; 19 head = second->next; 20 second->next = NULL; 21 return head; 22 } 23 };