题目:
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
.
思路:对于数组来说,右旋的方法是两轮逆转。对于链表,结点的位置是逻辑相连的,右旋时只需要拆开两截在另一头接上,不需要移动链的内部,更不需要交换结点的元素。所以操作的关键是根据数字k,找到链表拆解的位置。注意k可以超过链表元素的个数,即右旋几圈跟没右旋一样。
代码一:
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(head == NULL)
return NULL;
ListNode *p1, *p2;
p1 = p2 = head;
while(k > 0)
{
k--;
p1 = p1->next;
if(p1 == NULL)//循环跑圈,把k跑到0
p1 = head;
}
while(p1->next != NULL)
{
p1 = p1->next;
p2 = p2->next;
}//此时:p1指向链表尾结点,p2指向链表右旋位置
p1->next = head;
head = p2->next;
p2->next = NULL;
return head;
}
};
代码二:也可以先求出链表长度,然后通过取模运算来计算旋转位置。当k很大的时候可以避免代码一循环跑圈。
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(head == NULL || k == 0)
return head;
ListNode *p1, *p2;
p1 = p2 = head;
int n = 1;
while(p1->next != NULL) //计算链表长度并记录尾结点
{
n++;
p1 = p1->next;
}
k = n - k%n;
for(int i=1;i<k;i++) //找到新表尾
p2 = p2->next;
p1->next = head;
head = p2->next;
p2->next = NULL;
return head;
}
};