#递归的思路
#最初思路是把该链表分为以k为基数的组,然后每组进行reverse
#而每组其实构造是一致的,利用递归即可解决
# 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]:
if head ==None:
return None
point = head
#找到链表的尾部
i=k
while i>1:
point = point.next
if point.next!=None:
return head
i-=1
#将链表分割,并用tmp进行储存
tmp = point.next
point.next = None
#倒置新子链表,设置新的头结点
head_new = self.reverse_(head)
#此时倒置的haad节点为新链表的尾部(由于reverse),连接起来最后返回head_new
head.next = self.reverseKGroup(tmp,k)
return head_new
#反转链表
def reverse_(self,head):
#创建一个新空节点
#取出旧节点的元素,将其next指针设置为新链表的头指针,同时将旧链表的头结点执行下一个元素
#依次重复第2步的操作,直到取出就链表中所有的节点
current_head = None
while head!=None:
next = head.next
head.next = current_head
current_head = head
head = next
return current_head
#有点问题:还没找到具体原因
#大不了重头来过...
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
# 思路:算出整个链表长度,每k个分成一组,记录头尾节点
if head == None or head.next == None or k <= 1:
return head
dummy_head = ListNode(-1)
dummy_head.next = head
# 计算链表长度
list_len = 0
p = head
while p:
list_len += 1
p = p.next
# 计算需要反转的次数
total_times = list_len // k
prev = dummy_head
p = prev
while total_times > 0:
for i in range(k):
p = p.next
# 记录主链表的尾部
tail = p.next
link_head, link_tail = self.helper(prev.next, k) # 反转后链表的头尾指针
# 主链表和反转后的链表链接上
prev.next = link_head
link_tail.next = tail
# 更新下一个要反转节点的位置,以及它的头指针
prev = link_tail
p = prev
total_times -= 1
return dummy_head.next
# 部分反转链表
def helper(self, p, k): # 1-->2-->3
prev = p
tail = p # 最后的尾部节点也是它
cur = p.next
next = cur.next
for i in range(k - 1):
next = cur.next
cur.next = prev
prev = cur
cur = next
tail.next = None # tail.next==None,来防止成环
return prev, tail