25. K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:

给你这个链表:1->2->3->4->5
k = 2 时,应当返回: 2->1->4->3->5
k = 3 时,应当返回: 3->2->1->4->5

说明:

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

栈:

用栈,我们把k个数压入栈中,然后弹出来的顺序就是翻转的!

这里要注意几个问题
第一,剩下的链表个数够不够k个(因为不够k个不用翻转);
第二,已经翻转的部分要与剩下链表连接起来

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
  8. dummy = ListNode(0)
  9. p = dummy
  10. while True:
  11. count = k
  12. stack = []
  13. tmp = head
  14. while count and tmp:
  15. stack.append(tmp)
  16. tmp = tmp.next
  17. count -= 1
  18. # 注意,目前tmp所在k+1位置
  19. # 说明剩下的链表不够k个,跳出循环
  20. if count :
  21. p.next = head
  22. break
  23. # 翻转操作
  24. while stack:
  25. p.next = stack.pop()
  26. p = p.next
  27. #与剩下链表连接起来
  28. p.next = tmp
  29. head = tmp
  30. return dummy.next

递归:

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
  8. cur = head
  9. count = 0
  10. while cur and count < k:
  11. cur = cur.next
  12. count += 1
  13. # 此时cur指向第k+1个
  14. if count == k:
  15. cur = self.reverseKGroup(cur, k)
  16. while count:
  17. tmp = head.next # head指向本轮待排序,tmp指向下一个待排序
  18. head.next = cur # 将待排序的开头与排好序相接
  19. cur = head # 此时cur指向后端已排好序的开头
  20. head = tmp # head指向待排序的开头
  21. count -= 1
  22. head = cur
  23. return head