目录
题目
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
提示:
链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?
分析
1. 判断链表是否为空、是否只有一个节点,是则返回空链表或该节点。
2. 统计链表节点个数,得出链表长度 length 。每组子链表反转的节点数 k ,可计算出应反转子链表的组数 num = length / k。
3. 要满足空间复杂度为O(1),需要在原链表上操作。使用头插法将每组子链表反转。设置计数器 count,控制反转组数为 num次。
代码实现
public class Num25_reverseKGroup { public ListNode reverseKGroup(ListNode head, int k) { //判空 if (head == null || head.next == null) { return head; } //此时链表至少有两个节点 ListNode x = head; int length = 0; while (x != null) { //统计链表的长度 length++; x = x.next; } int num = length / k; //计算需要反转的组数 int count = 0; //设置计数器,控制反转的组数 ListNode dummyHead = new ListNode(); dummyHead.next = head; ListNode prev = dummyHead; ListNode cur = prev.next; ListNode next = new ListNode(); while (count < num) { for (int i = 0; i < k - 1; i++) { //头插法反转链表,一次循环,反转一组 next = cur.next; cur.next = next.next; next.next = prev.next; prev.next = next; } prev = cur; cur = prev.next; count++; } return dummyHead.next; } }
时间复杂度:O(n) 最坏情况下,整个链表的每个节点分别会被遍历 1 次、翻转一次。
空间复杂度:O(1) 除了必须的节点指针外,并没有占额外空间。
如有Bug,望指正,感谢浏览 !