NC50 链表中的节点每k个一组翻转

1. 题目

将给出的链表中的节点每 k k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度  O(1) O(1)
 
例如:
给定的链表是1 o2 o3 o4 o512345
对于  k = 2 k=2, 你应该返回 2 o 1 o 4 o 3 o 521435
对于  k = 3 k=3, 你应该返回 3 o2 o1 o 4 o 532145

2. 示例

输入:{1,2,3,4,5},2
返回值:{2,1,4,3,5}

3. 题解

放图(此图转自牛客大佬,谢谢带来的帮助,(#^.^#))

此题是链表里的一个绝对经典的题,对所有人都有很大的帮助,所以写下来了。

本题最关键的是如何不引入额外空间的情况,实现翻转。

其根本考察的是对链表的插入和删除。

本题将其定位到一个局部进行操作,有三个关键的字段:pre, cur, temp。

pre是每一小段的头结点,负责衔接;

cur用来行走链表,其实相当于已遍历过的尾结点,其下面一个就是即将插入头部的节点。

temp用来存储需要删除的以及即将插入头部的节点。

 4. Code实现

 1 class Solution:
 2     def reverseKGroup(self, head, k):
 3         if not head or k <= 1:
 4             return head
 5         root, n = head, 0
 6         # 统计节点个数
 7         while root:
 8             n += 1
 9             root = n
10         res = ListNode(0)
11         res.next = head
12         pre, cur, temp = res, head, None
13         # 分段使用头插法将链表反序
14         for i in range(0, n // k):
15             # pre作为每一小段的头结点,负责衔接
16             for j in range(1, k):
17                 temp = cur.next
18                 cur.next = temp.next
19                 temp.next = pre.next
20                 pre.next = temp
21             # 每个子序列反序完成后,pre,cur需要重新更新到下一子序列的头部
22             pre = cur
23             cur = cur.next
24         return res.next

5. 结语

  努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!

  如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。

但行好事 莫问前程
原文地址:https://www.cnblogs.com/haifwu/p/15112607.html