题目:
给你一个链表的头节点 head
。
链表中的节点 按顺序 划分成若干 非空 组,这些非空组的长度构成一个自然数序列(1, 2, 3, 4, ...
)。一个组的 长度 就是组中分配到的节点数目。换句话说:
- 节点
1
分配给第一组 - 节点
2
和3
分配给第二组 - 节点
4
、5
和6
分配给第三组,以此类推
注意,最后一组的长度可能小于或者等于 1 + 倒数第二组的长度
。
反转 每个 偶数 长度组中的节点,并返回修改后链表的头节点 head
。
思路:
代码:
class Solution {
public ListNode reverseEvenLengthGroups(ListNode head) {
ListNode dummyNode = new ListNode(0, head);
int group = 1; // 表示链表组数
// head 表示每一组的头结点, tail表示每一组尾节点,
// pre表示每一组头结点的前驱(前一组的尾节点), cur表示遍历指针
ListNode cur = head, pre = dummyNode, tail = dummyNode;
while (head != null) {
int count = 0; // 表示每一组的节点个数
while (count < group && cur != null) {
tail = cur;
cur = cur.next;
count++;
}
// cur刚好每次遍历到下一组的头结点
if (count % 2 == 0) { // 处理偶数组或最后一组有偶数个节点
ListNode newHead = reverse(head, cur);
// 反转之后: head变为尾节点,newHead变为头结点
pre.next = newHead;
head.next = cur;
pre = head;
} else { // 奇数组或最后一组有奇数个节点
pre = tail;
}
head = cur;
group++;
}
return dummyNode.next;
}
// [start, end)
private ListNode reverse(ListNode start, ListNode end) {
ListNode cur = start, pre = null;
while (cur != end) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
性能:
时间复杂度o(n)
空间复杂度o(1)