题目:
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例1:
示例2:
热度:5/100
cpp代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
//官方做法:
//翻转一个子链表,并且返回新的头与尾,此函数没有按照官方做法写的,而是参照了【反转链表】的做法
pair<ListNode*,ListNode*> myReverse(ListNode* head,ListNode* tail){
//if(head==tail) return {head,tail};
ListNode* h = head; //保留头节点,也是返回的尾节点
ListNode* pre = head; //前指针
ListNode* nxt = head->next; //后指针
pre->next = nullptr; //头节点的下一个节点指向空
while(pre!=tail){ //注意:while的判断条件是:pre!=tail而不是nxt!=nullptr
ListNode* temp = nxt->next;
nxt->next = pre;
//更新指针
pre = nxt;
nxt = temp;
}
//while结束后,pre指向了tail
return {pre,h};
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(k==1) return head; //如果k=1,直接返回原链表
ListNode* hair = new ListNode(0); //伪头节点
hair->next = head;
ListNode* pre = hair; //保存 要反转链表的前一个节点
while(head){
ListNode* tail = pre; //尾节点从要反转链表的前一个节点开始移动,便于计数
// 查看剩余部分长度是否大于等于 k
for(int i=0;i<k;++i){
tail = tail->next; //tail移动,移动k个后,到达了反转链表的尾部
if(!tail){ //如果剩余节点不足k个,说明反转工作完成,直接返回
return hair->next;
}
}
ListNode* nex = tail->next; //保存 下一个反转链表的头节点
//此时head和tail分别指向了要反转链表的头节点和尾节点,将该链表反转
pair<ListNode*,ListNode*> newList = myReverse(head,tail);
// 把子链表重新接回原链表
pre->next = newList.first; //pre的下一个节点指向 新链表的头节点
newList.second->next = nex; //新链表的尾节点的下一个节点指向 反转之前链表尾节点的下一个节点
//更新pre和head
pre = newList.second; //pre指向新链表的尾节点,用于连接下一个反转的链表
head = nex; //head指向将要反转链表的第一个节点
}
return hair->next;
}
};