题目:将链表的后k个节点转到前面,这k个节点的顺序保持不变,其中k为非负数。
这是一道双指针方法的题,思路本身并不难,这道题的难点是代码的鲁棒性!
思路:
- 创建两个指针,他们之间相差k步;
- 同时递进两个指针,直到第二个指针的next指向nullptr,这时我们就确定了要旋转的区间;
- 旋转链表;
鲁棒性:
- 首先就是head为nullptr时,代码不能崩溃;
- 题目中说k是非负数,那么k为0时程序不能崩溃,且结果要正确(也就是链表不变),k大于等于链表的长度时呢?
我们直接来看代码:
/**
* 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)
{
//处理head为nullptr时以及k小于0时的情况
if(!head || k < 0) return nullptr;
//使用两个指针来确定需要旋转的范围
ListNode *s = head;
ListNode *e = head;
//先将e递进k步
for(int i = 0; i < k; ++i)
{
e = e->next;
//需要处理k超过链表长度的情况
if(!e)
{
k %= (i + 1);
e = head;
i = -1;
}
}
//k为0,或者k为链表长度的整数倍
if(e == head) return head;
//确定需要旋转的区间
while(e->next != nullptr)
{
s = s->next;
e = e->next;
}
//旋转
e->next = head;
head = s->next;
s->next = nullptr;
return head;
}
};
下面是运行结果: