「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。
题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗? 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]
思路分析
在做过翻转链表以后,这道题就不算困难了,至少思路上很容易理解。
- 先判断是否需要翻转:剩余长度是否大于等于k
- 对接下来k个节点进行翻转
- 循环上面两步
为了方便起见,我们将第二步操作和第一步操作提取出来
pair<ListNode*, ListNode*> reverseK(ListNode* node, ListNode* tail){
ListNode* tmp = node;
ListNode* pre = tail -> next;
while(tmp != tail){
ListNode* tt = tmp -> next;
tmp -> next = pre;
pre = tmp;
tmp = tt;
}
tmp -> next = pre;
return {tail, node};
}
bool isNeed(ListNode* node, int k){
ListNode* tmp = node;
for(int i = 0; i < k; i ++){
if (tmp != nullptr){
tmp = tmp -> next;
}else{
return false;
}
}
return
}
实操的时候打的代码有很多问题,经过排查后其实是对于翻转后的一组节点,没有将它连到整个长链路中。导致会出现节点的缺失。
具体实现
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* node = head;
ListNode* hair = nullptr;
ListNode* pre = hair;
ListNode* ret =nullptr;
bool flag = true;
while(isNeed(node, k)){
ListNode* nex = getKNode(node, k);
// cout << node->val << endl;
ListNode* wei = getK1Node(node, k);
tie(node, wei) = reverseK(node, wei);
// cout << pre << endl;
if(flag){
ret = node;flag = false;
}
if (pre != nullptr){
pre ->next = node;
}
wei -> next = nex;
node = wei -> next;
// cout << pre << " " << wei->val<< endl;
pre = wei;
// cout << pre->val << " " << wei->val<< endl;
}
return ret;
}