标题:奇偶链表
出处:328. 奇偶链表
4 级
给你一个链表的头结点 head \texttt{head} head,把所有的奇数下标结点排在前面的组,把所有的偶数下标结点排在后面的组,返回重新排列后的链表。
链表的第一个结点视为奇数结点,第二个结点视为偶数结点,以此类推。
在奇数组和偶数组内部的结点的相对顺序应和输入保持一致。
要求空间复杂度为 O(1) \texttt{O(1)} O(1),时间复杂度为 O(n) \texttt{O(n)} O(n)。
示例 1:
输入: head = [1,2,3,4,5] \texttt{head = [1,2,3,4,5]} head = [1,2,3,4,5]
输出: [1,3,5,2,4] \texttt{[1,3,5,2,4]} [1,3,5,2,4]
示例 2:
输入: head = [2,1,3,5,6,4,7] \texttt{head = [2,1,3,5,6,4,7]} head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4] \texttt{[2,3,6,7,1,5,4]} [2,3,6,7,1,5,4]
如果链表为空,则直接返回空链表即可。当链表不为空时,链表中的每个结点都是奇数结点或偶数结点,且相邻结点的奇偶性不同,因此可以将原始链表分离成奇数链表和偶数链表,然后将偶数链表拼接在奇数链表之后,即完成了链表的重新排列。
原始链表的头结点 head \textit{head} head 也是奇数链表的头结点和结果链表的头结点, head \textit{head} head 的后一个结点是偶数链表的头结点,即 evenHead = head . next \textit{evenHead} = \textit{head}.\textit{next} evenHead=head.next 是偶数链表的头结点。
维护两个指针 odd \textit{odd} odd 和 even \textit{even} even 分别指向奇数结点和偶数结点,初始时 odd = head \textit{odd} = \textit{head} odd=head, even = evenHead \textit{even} = \textit{evenHead} even=evenHead。每一步操作更新 odd . next \textit{odd}.\textit{next} odd.next 和 even . next \textit{even}.\textit{next} even.next 指向的结点,使得 odd . next \textit{odd}.\textit{next} odd.next 和 even . next \textit{even}.\textit{next} even.next 分别指向下一个奇数结点和下一个偶数结点,在更新当前奇偶结点的 next \textit{next} next 的指向之后,将 odd \textit{odd} odd 和 even \textit{even} even 分别向后移动一步,到下一个奇数结点和偶数结点。
具体做法为依次执行以下 4 4 4 步操作:
上述 4 4 4 步操作完成一个奇数结点和一个偶数结点的分离,并将奇数结点和偶数结点移动到下一个奇数结点和下一个偶数结点。重复上述操作,直到全部结点分离完毕。
全部结点分离完毕时, odd \textit{odd} odd 指向最后一个奇数结点, even \textit{even} even 指向 null \text{null} null 或者最后一个偶数结点,取决于链表长度(结点数)是奇数或者偶数。
全部结点分离完毕之后,由于 odd \textit{odd} odd 指向最后一个奇数结点,因此将 evenHead \textit{evenHead} evenHead 拼接在 odd \textit{odd} odd 之后,即完成了链表的重新排列。结果链表的头结点是 head \textit{head} head。
下图为示例 1 的重新排列链表的过程。奇数结点和偶数结点分别在两行,绿色和蓝色分别表示 odd \textit{odd} odd 和 even \textit{even} even 指向的结点。
class Solution {
public ListNode oddEvenList(ListNode head) {
if (head == null) {
return head;
}
ListNode odd = head, even = head.next, evenHead = head.next;
while (even != null && even.next != null) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
}
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的长度。需要遍历链表一次,对每个结点分离和合并操作都是 O ( 1 ) O(1) O(1) 的时间。
空间复杂度: O ( 1 ) O(1) O(1)。