题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
只要我们会对链表进行一个翻转就行了,然后就是对每一组的头部与尾部的处理,我把翻转的代码写好之后,直接把别人的java版本的代码转为C++ 版本的 . . .
.
相关代码文章如下所示:
LeetCode算法 —— 反转链表(递归 + 迭代)
代码如下所示:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if (head == nullptr || head->next == nullptr)
return head;
ListNode* retList = new ListNode(0);
retList->next = head;
ListNode* pre = retList; // 指向当前组的头
ListNode* end = retList; // 指向当前组的最后一个节点
while (end->next) {
// 遍历到当前组的最后一个节点
for (int i = 0; i < k && end != nullptr; i++)
end = end->next;
if (end == nullptr) break;
ListNode* start = pre->next; // 当前组的第一个节点
ListNode* next = end->next; // 保存下一组的第一个节点的指针
end->next = nullptr; // 先将当前组与下一组断开链接(便于翻转)
pre->next = reverse(start); // 翻转当前组,并返回最新的头指针
start->next = next; // 此时 start 表示当前组的最后一个节点,与下一组进行连接
pre = start; // pre 变为下一组的头指针
end = pre; // 为获取下一组的最后一个节点作准备
}
return retList->next;
}
private:
// 对链表进行翻转
ListNode* reverse(ListNode* head) {
if (head == nullptr || head->next == nullptr)
return head;
ListNode* pre = new ListNode(0);
pre->next = head;
ListNode* tmp = head;
while (tmp != nullptr && tmp->next != nullptr) {
ListNode* start = tmp->next; // 当前需要操作的结点
pre->next = start;
tmp->next = start->next;
start->next = head;
head = start;
}
return head; // 返回头指针
}
};
int main() {
ListNode* p = new ListNode(1);
p->next = new ListNode(2);
p->next->next = new ListNode(3);
p->next->next->next = new ListNode(4);
p->next->next->next->next = new ListNode(5);
ListNode* tmp = (new Solution())->reverseKGroup(p, 3);
while (tmp) {
cout << tmp->val << endl;
tmp = tmp->next;
}
return 0;
}