题目
将给出的链表中的节点每\ k k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是\ k k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度 \ O(1) O(1)
例如:
给定的链表是1\to2\to3\to4\to51→2→3→4→5
对于 \ k = 2 k=2, 你应该返回 2\to 1\to 4\to 3\to 52→1→4→3→5
对于 \ k = 3 k=3, 你应该返回 3\to2 \to1 \to 4\to 53→2→1→4→5
解析
题目可以分解成很多个链表段,每个链表段执行反转操作。反转链表具体可以看我这个博客
牛客网 | 高频面试题 | 反转链表_我是一块小石头-CSDN博客
具体步骤分为3步:
- 遍历链表,找到需要反转的链表段
- 反转目标链表段
- 将目标链表段接入原链表
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
//反转目标链表段
pair<ListNode*, ListNode*> myReverse(ListNode* head,ListNode* tail){
ListNode* prev = tail->next;
ListNode* p=head;
while(prev!=tail){
ListNode* nex = p->next;
p->next=prev;
prev=p;
p=nex;
}
return {tail, head};
}
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* reverseKGroup(ListNode* head, int k) {
// write code here
ListNode* hair = new ListNode(0);
hair->next = head;
ListNode* pre = hair;//记录反转的链表段的pre指针,用于之后的拼接
while(head){
//遍历链表,判断长度,并记录需要反转的链表段的头尾~
ListNode* tail = pre;
for(int i=0;i<k;++i){
if(tail->next != nullptr){
tail = tail->next;
}else{
return hair->next;
}
}
ListNode* nex = tail->next;//记录反转的链表段的tail->next指针,用于之后的拼接
pair<ListNode*, ListNode*> result = myReverse(head, tail);
head = result.first;
tail = result.second;
pre->next = head;
tail->next = nex;
pre = tail;
head = pre->next;
}
return hair->next;
}
};