给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3 输出:[3,2,1,4,5]
提示:
- 链表中的节点数目为
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
进阶:你可以设计一个只用 O(1)
额外内存空间的算法解决此问题吗?
——————————————————————————————————————
哈哈,这是解决的第一个困难题,也是照着进阶的方向写的,用时击败98%;
思路也比较简单(脑袋想不出什么简单便捷的方式 qwq
遍历一遍链表,得到长度length,随后计算出需要反转的块数 = length // k,
对于每个块使用头插法,记录好每个块反转后的头节点和尾节点,做好每一块之间的连接即可
- 时间复杂度: O(n)
- 空间复杂度: O(1)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
# 特殊情况 若k=1直接不用反转了
if k == 1:return head
res = None
a = head
length = 0
while a !=None:a,length = a.next,length+1
# 计算反转次数
reverse_times = length//k
a,b = head,head.next
# 记录反转后的前、后节点
wei_q = a
wei_h = None
while reverse_times > 0:
# 每次反转 用头插法
for i in range(k-1):
if i == 0:
wei_h = a
wei_h.next = None
tmp = a
a = b
b = a.next
a.next = tmp
if i == k-2:wei_q = a
if reverse_times == length//k:
# 若第一次反转:存一下结果返回节点
res = wei_q
if reverse_times != length//k:
# 若不是第一次反转:完成每块之间的连接
pre_h.next = wei_q
pre_h = wei_h
pre_q = wei_q
a = b
if a!=None:b = a.next
if a == None or b == None:break
reverse_times -= 1
pre_h.next = a
pre_h.next = a
return res