问题: 旋转链表
解题思路
先将单链表的尾节点链接到头节点形成循环链表,然后定位到旋转后的链表的头节点,并从此处断开即可。设链表长度为n,那么链表向右移动n的倍数个位置后仍然是原链表,因此将k%n。如何定位旋转后的链表的头节点?当向右移动1个位置,新头节点为倒数第1个,当向右移动2个位置,新头节点为倒数第2个…向右移动k%n个位置,新的头节点为倒数第k%n个,于是可以将 cur = head,向后移动n - k % n次即可
C++代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(k == 0 || !head) return head;//不用移动
int n = 0;//统计链表节点总数
ListNode *pre = NULL, *cur = head;
while(cur){
n++;
pre = cur;
cur = cur->next;
}
k %= n;//让k模除节点总数
//此时pre指向最后一个节点
//将最后一个节点和第一个节点连起来,构成循环链表
pre->next = head;
//定位旋转后的链表的新的头节点
pre = NULL, cur = head;
for(int i = 1; i <= n - k; i++){//cur向后走n-k步
pre = cur;
cur = cur->next;
}
//此时cur是头节点,pre是最后一个节点了,将它们断开
pre->next = NULL;
//返回移动后的链表的头节点
return cur;
}
};