描述
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
1 2 3 4 5
| 输入: 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:
1 2 3 4 5 6 7
| 输入: 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
|
来源:力扣(LeetCode)
链接:61. Rotate List
解题思路
本题需要注意的是k有可能大于链表的长度,这个在示例2里面也已经给出来了,所以在求解之前需要获得链表的长度。
然后需要处理极端条件,就是链表长度为0时,直接返回NULL。
如果链表长度为length,则需要用k对length取模,取模后的startIndex才是需要进行旋转的位置。
startIndex确定下来以后采用快慢指针,快指针先走startIndex步,然后两个指针一起走,当快指针走到末尾时,慢指针的下一个位置是新的顺序的头结点。
这里先将快指针的next指向head,相当于先将链表成环,然后将快指针移到慢指针的next,最后将慢指针的next指向NULL,相当于将环打断,最后返回快指针头节点。
具体示意图如下:

具体代码如下:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
int getLength(struct ListNode* head) { int count = 0; while(head) { count++; head = head->next; } return count; }
struct ListNode* rotateRight(struct ListNode* head, int k) { if(!head) return NULL; struct ListNode *rotated = head; int length = getLength(rotated); int startIndex = k % length; struct ListNode *result = head, *slow = head; for(int i = 0; i < startIndex; i++) { if(result) result = result->next; } if(!result) return head; while(result->next) { result = result->next; slow = slow->next; } result->next = head; result = slow->next; slow->next = NULL; return result; }
|