链表翻转。给出一个链表和一个数K,比如链表1->2->3->4->5->6->NULL,K=2,翻转后 2->1->4->3->6->5->NULL,若K=3,翻转后3->2->1->6->5->4->NULL,若K=4,翻转后4->3->2->1->5->6->NULL,用程序实现
ListNode* RotateList(ListNode* list, size_t k)
。
递归实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *reverseKGroup(ListNode *head, int k) {
// 为空或一个结点或 K 不符合 规范直接返回原head
if( NULL == head || NULL == head->next || k < 2)
return head;
// 以k为步数,找到逆置前下一组的头指针
ListNode* next_group_head = head;
for(int i = 0; i < k; ++i){
if(next_group_head)
next_group_head = next_group_head->next;
else // 剩余结点数小于K 不够分一组时,下一组的头指针就是head
return head;
}
// 递归去处理剩余组,直到不够 K 个结点,即求出下一组逆置后的头指针
ListNode* new_next_group_head = reverseKGroup(next_group_head, k);
ListNode* prev = NULL ,* cur = head;
// 开始逆置处理当前组,从 head --- next_group_head下一组逆置前的第一个结点
while(cur != next_group_head){
ListNode* next = cur->next; // 保存下一个结点
if(prev == NULL) // 为空则将当前组的一个结点指向下一组逆置后的第一个结点
cur->next = new_next_group_head;
else // 不为空则表示逆置当前组的结点,指向prev即可
cur->next = prev;
prev = cur; // 向后推进,直到走完当前组
cur = next;
}
// 返回逆置后的头指针
return prev;
}
};
迭代解法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *reverseKGroup(ListNode *head, int k)
{
// 特殊情况处理
if (NULL == head || NULL == head->next || k < 2)
return head;
ListNode* prev = NULL, *pcur = head, *newhead = NULL;
// 遍历链表,处理每一组
while (pcur){
// 找到下一组的头
ListNode* next_group_head = pcur;
int i = 0;
for (; next_group_head && i < k; i++){
next_group_head = next_group_head->next;
}
// 处理不足K 个元素的组
if (i < k ){
// 防止K 大于链表结点
if (newhead == NULL)
newhead = head;
break;
}
// 将当前分组[pcur, next_group_head) 逆置,并返回逆置后的头指针
ListNode* tmp = reverse(pcur, next_group_head);
if (prev == NULL) // 第一个分组需要更新新的头指针
newhead = tmp;
else // 后续只需要将上一个分组的最后一个结点next 指向当前分组逆序后的的头指针
prev->next = tmp;
// 当前分组的最后一个结点next 指向下一个分组开始
pcur->next = next_group_head;
// prev 保存当前分组的最后一个结点
prev = pcur;
// pcur 向后推进到下一个分组的开始
pcur = next_group_head;
}
return newhead;
}
// [start, end)
ListNode* reverse(ListNode* start, ListNode* end)
{
ListNode* prev = NULL;
ListNode* pcur = start;
while (pcur != end){
ListNode* next = pcur->next;
pcur->next = prev;
prev = pcur;
pcur = next;
}
return prev;
}
};