Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL
and k = 2
,
return 4->5->1->2->3->NULL
例如:
给定链表 1->2->3->4->5->NULL 和 k = 2,返回 4->5->1->2->3->NULL。
分析:
首先将指向首节点的指针 p 移动 k 个节点,同时记录链表的长度 listSize,如果 p 还没移动 k 就到达链表尾,则需要 k = k%listSize 重新求的 k 值(因为翻转 listSize 的整数倍和不翻转是一样的)并重新移动 k 个节点,然后再将指向表头的另一个指针 rotateNode 跟随 p 移动,当 p 到达结尾时,rotateNode 指向需要翻转位置的前一个节点,此时只需要将翻转的位置和链表头重新连接即可。
struct ListNode* rotateRight(struct ListNode* head, int k) {
/* 首先找出需翻转的位置,同时记录链表的长度listSize
* 如果 k > listSize,则 k = k % listSize; 否则重复翻转
*/
int listSize = 0;
int count = 0;
struct ListNode *rotateNode = head, *p = head;
/*空指针或一个节点或不翻转*/
if(!head || !head->next || 0 == k)
{
return head;
}
while(p && count < k)/*指针先移动k,使最终翻转位置距链表尾相隔k*/
{
p = p->next;
++listSize;
++count;
}
if(!p) /*k > listSize*/
{
k = k % listSize;
if(0 == k) /*k为链表长度的倍数,不用翻转*/
{
return head;
}
p = head;
count = 0;
while(count++ < k)/*重新移动k*/
{
p = p->next;
}
}
while(p->next)
{
rotateNode = rotateNode->next;
p = p->next;
}
p->next = head; /*翻转*/
head = rotateNode->next;
rotateNode->next = NULL;
return head;
}