题目链接
https://leetcode.cn/problems/reverse-nodes-in-k-group/description/
题解链接
题解
我的想法是暴力法,统计出一整个数组,然后每次统计出k个数值调用API反转,并根据反转后的数组整体重新创建一个新的链表(跟之前面字节面试的时候一样)。
题解一:栈
他这个其实也是双指针法,各种提取和连接比较巧妙,还有他中途返回,不熟悉可能做不出来。
题解二:深度优先搜索、递归
和上一个解法都是使用了while True。就是反转链表的时候用到了dfs算法,其余也是需要结点个数的处理,循环重新赋值等等细节。但是这个题解写的不好,罗里吧嗦一大堆,变量命名也不规范,看了根本分不清。
题解三:链表
时间复杂度我分析错了,是O(n)不是O(n* k)。

画了个图,理解一点了最后几句,有点绕,p0每次保存的是当前处理这组k个结点的最后一个结点,也就是本组的第一个结点。
代码
python
#25.K 个一组翻转链表
#题解一:栈
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
h = t = ListNode(0, head)
p, stack = head, []
while True:
for _ in range(k):
if p:
stack.append(p) # 压栈
p = p.next
else: return h.next # 不满栈,直接返回
for _ in range(k):
t.next = stack.pop() # 出栈,同时续到链表尾部
t = t.next
t.next = p # 连接后段链表
#题解二:深度优先搜索、递归
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
def getK(k, start):
# get 第 n*k + 1 个节点
curr = start
for i in range(k):
if not curr:
# 不够 k 个,要区分于 None
# 否则,无法区分 "最后一个节点恰好是第 n*k 个" 的情况
# (因为那时的第 n*k + 1 个节点为 None,且仍然需要经历 dfs 处理,不能提前 return)
return -1
curr = curr.next
return curr
def dfs(pre, head, end):
if head == end:
return pre, head
nxt = head.next
head.next = pre
return dfs(head, nxt, end)
# 准备一个虚拟头节点,用于最后返回结果
dummy = ListNode(-1)
# 根据循环的规律,提前设置好「节点 b 和 节点 d」
b = dummy
d = head
while True:
# 准备 「节点 a 和 节点 b」
a, b = b, d
# 找到「节点 d」,是 dfs 反转链表时的结束条件
# 第 n*k + 1 个节点,dfs 反转链表时遇到了它,就应该结束反转
d = getK(k, b)
# 如果余下的节点不够 k 个,直接返回虚拟头节点的 next
if d == -1:
return dummy.next
# 反转子链表(长度为 k)
c, d = dfs(None, b, d)
# 穿针引线
a.next, b.next = c, d
# 如果总节点个数是 k 的倍数,那么就会遇到节点 d 为空的时候,直接返回虚拟头节点的 next
if not d:
return dummy.next
#题解三:链表
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
# 统计节点个数
n = 0
cur = head
while cur:
n += 1
cur = cur.next
p0 = dummy = ListNode(next=head)
pre = None
cur = head
# k 个一组处理
while n >= k:
n -= k
for _ in range(k): # 同 92 题
nxt = cur.next
cur.next = pre # 每次循环只修改一个 next,方便大家理解
pre = cur
cur = nxt
# 见视频
nxt = p0.next
nxt.next = cur
p0.next = pre
p0 = nxt
return dummy.next