先找第 k 个节点,翻转这一段并接回;不足 k 段保持原样。
OJ: leetcodecn
题目 ID: reverse-nodes-in-k-group
难度:提高+/省选-
标签:链表递归cpppython
日期: 2026-07-28 22:05
题意
每 k 个节点一组翻转链表,不足 k 的保持原样。
思路
递归版:先检查是否有 k 个节点,有则递归处理后续部分,再翻转当前段。迭代版更节省空间:用 dummy 和 prev 指针维护已翻转到未处理的边界,每轮找到第 k 个节点后翻转段内指针。
代码
cpp
/**
* Author by Rainboy
*/
// main.cpp:先找第 k 个节点,翻转这一段并接回;不足 k 段保持原样。
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
ListNode *reverseKGroup(ListNode *head, int k) {
ListNode dummy(0);
dummy.next = head;
auto prev = &dummy;
while (true) {
auto end = prev;
for (int i = 0; i < k && end; i++)
end = end->next;
if (!end)
break;
auto start = prev->next, nxt = end->next;
auto a = start, b = a->next;
while (b != nxt) {
auto c = b->next;
b->next = a;
a = b;
b = c;
}
start->next = nxt;
prev->next = a;
prev = start;
}
return dummy.next;
}
};
ListNode *build(istream &in, int n) {
if (!n)
return nullptr;
auto head = new ListNode(0), cur = head;
for (int i = 0, v; i < n; i++) {
in >> v;
cur->next = new ListNode(v);
cur = cur->next;
}
return head->next;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n >> k;
auto head = build(cin, n);
head = Solution().reverseKGroup(head, k);
for (auto p = head; p; p = p->next)
cout << p->val << ' ';
return 0;
}python
#!/usr/bin/env python3
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
prev = dummy
while True:
end = prev
for _ in range(k):
end = end.next
if not end:
return dummy.next
start = prev.next
nxt = end.next
a, b = start, start.next
while b is not nxt:
c = b.next
b.next = a
a = b
b = c
start.next = nxt
prev.next = a
prev = start
def build(arr):
dummy = cur = ListNode(0)
for v in arr:
cur.next = ListNode(v)
cur = cur.next
return dummy.next
def main() -> None:
n, k = map(int, input().split())
a = list(map(int, input().split()))
head = build(a)
head = Solution().reverseKGroup(head, k)
while head:
print(head.val, end=" ")
head = head.next
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n)。
- 空间复杂度:O(1) 迭代,O(n/k) 递归。
总结
K 个一组翻转是链表操作的综合练习,需要同时处理"寻找段尾"、“段内翻转”、"衔接前后"三个子任务。