题意
将给出的链表中的节点每 k
个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k
的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度 O(1)
例如:
给定的链表是1→2→3→4→5
对于k=2
, 你应该返回 2→1→4→3→5
对于k=3
, 你应该返回 3→2→1→4→5
题解
这道题是有子问题的,比如翻转第一次 k
个数后,后面的问题跟整个问题一样,所以可以用递归,详情看代码
首先实现一个反转整个链表的代码,这里用迭代法实现,当然递归也可以
ListNode* reverseList(ListNode* head)
{
ListNode* pre, *cur, *nxt;
pre = nullptr, cur = head, nxt = head;
while(cur != nullptr){
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
如果改为反转[a, b]
之间的结点,只需要更改函数为
ListNode* reverseBetween(ListNode* a, ListNode* b)
{
ListNode* pre, *cur, *nxt;
pre = nullptr, cur = a, nxt = a;
while(cur != b){
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
准备条件做好后,就按照递归的逻辑写就好
ListNode* reverseKGroup(ListNode* head, int k) {
if (head == nullptr) return nullptr;
// 区间 [a, b) 包含 k 个待反转元素
ListNode *a, *b;
a = b = head;
for (int i = 0; i < k; i++) {
// 不足 k 个,不需要反转,base case
if (b == nullptr) return head;
b = b->next;
}
// 反转前 k 个元素
ListNode newHead = reverse(a, b);
// 递归反转后续链表并连接起来
a->next = reverseKGroup(b, k);
return newHead;
}