题目

标题和出处

标题:奇偶链表

出处:328. 奇偶链表

难度

4 级

题目描述

要求

给你一个链表的头结点 链表题目:奇偶链表 - 图1,把所有的奇数下标结点排在前面的组,把所有的偶数下标结点排在后面的组,返回重新排列后的链表。

链表的第一个结点视为奇数结点,第二个结点视为偶数结点,以此类推。

在奇数组和偶数组内部的结点的相对顺序应和输入保持一致。

要求空间复杂度为 链表题目:奇偶链表 - 图2%7D#card=math&code=%5Ctexttt%7BO%281%29%7D&id=aIbf6),时间复杂度为 链表题目:奇偶链表 - 图3%7D#card=math&code=%5Ctexttt%7BO%28n%29%7D&id=WhkCd)。

示例

示例 1:

链表题目:奇偶链表 - 图4

输入:链表题目:奇偶链表 - 图5
输出:链表题目:奇偶链表 - 图6

示例 2:

链表题目:奇偶链表 - 图7

输入:链表题目:奇偶链表 - 图8
输出:链表题目:奇偶链表 - 图9

数据范围

  • 链表中结点数目为 链表题目:奇偶链表 - 图10
  • 链表题目:奇偶链表 - 图11
  • 链表题目:奇偶链表 - 图12

解法

思路和算法

如果链表为空,则直接返回空链表即可。当链表不为空时,链表中的每个结点都是奇数结点或偶数结点,且相邻结点的奇偶性不同,因此可以将原始链表分离成奇数链表和偶数链表,然后将偶数链表拼接在奇数链表之后,即完成了链表的重新排列。

原始链表的头结点 链表题目:奇偶链表 - 图13 也是奇数链表的头结点和结果链表的头结点,链表题目:奇偶链表 - 图14 的后一个结点是偶数链表的头结点,即 链表题目:奇偶链表 - 图15 是偶数链表的头结点。

维护两个指针 链表题目:奇偶链表 - 图16链表题目:奇偶链表 - 图17 分别指向奇数结点和偶数结点,初始时 链表题目:奇偶链表 - 图18链表题目:奇偶链表 - 图19。每一步操作更新 链表题目:奇偶链表 - 图20链表题目:奇偶链表 - 图21 指向的结点,使得 链表题目:奇偶链表 - 图22链表题目:奇偶链表 - 图23 分别指向下一个奇数结点和下一个偶数结点,在更新当前奇偶结点的 链表题目:奇偶链表 - 图24 的指向之后,将 链表题目:奇偶链表 - 图25链表题目:奇偶链表 - 图26 分别向后移动一步,到下一个奇数结点和偶数结点。

具体做法为依次执行以下 链表题目:奇偶链表 - 图27 步操作:

  1. 链表题目:奇偶链表 - 图28 指向 链表题目:奇偶链表 - 图29,更新后的 链表题目:奇偶链表 - 图30 指向下一个奇数结点;
  2. 链表题目:奇偶链表 - 图31,将 链表题目:奇偶链表 - 图32 移动到下一个奇数结点;
  3. 链表题目:奇偶链表 - 图33 指向 链表题目:奇偶链表 - 图34,更新后的 链表题目:奇偶链表 - 图35 指向下一个偶数结点;
  4. 链表题目:奇偶链表 - 图36,将 链表题目:奇偶链表 - 图37 移动到下一个偶数结点。

上述 链表题目:奇偶链表 - 图38 步操作完成一个奇数结点和一个偶数结点的分离,并将奇数结点和偶数结点移动到下一个奇数结点和下一个偶数结点。重复上述操作,直到全部结点分离完毕。

全部结点分离完毕时,链表题目:奇偶链表 - 图39 指向最后一个奇数结点,链表题目:奇偶链表 - 图40 指向 链表题目:奇偶链表 - 图41 或者最后一个偶数结点,取决于链表长度(结点数)是奇数或者偶数。

全部结点分离完毕之后,由于 链表题目:奇偶链表 - 图42 指向最后一个奇数结点,因此将 链表题目:奇偶链表 - 图43 拼接在 链表题目:奇偶链表 - 图44 之后,即完成了链表的重新排列。结果链表的头结点是 链表题目:奇偶链表 - 图45

下图为示例 1 的重新排列链表的过程。奇数结点和偶数结点分别在两行,绿色和蓝色分别表示 链表题目:奇偶链表 - 图46链表题目:奇偶链表 - 图47 指向的结点。

17_1.png

代码

  1. class Solution {
  2. public ListNode oddEvenList(ListNode head) {
  3. if (head == null) {
  4. return head;
  5. }
  6. ListNode odd = head, even = head.next, evenHead = head.next;
  7. while (even != null && even.next != null) {
  8. odd.next = even.next;
  9. odd = odd.next;
  10. even.next = odd.next;
  11. even = even.next;
  12. }
  13. odd.next = evenHead;
  14. return head;
  15. }
  16. }

复杂度分析

  • 时间复杂度:链表题目:奇偶链表 - 图49#card=math&code=O%28n%29&id=cTaVp),其中 链表题目:奇偶链表 - 图50 是链表的长度。需要遍历链表一次,对每个结点分离和合并操作都是 链表题目:奇偶链表 - 图51#card=math&code=O%281%29&id=uFvZw) 的时间。
  • 空间复杂度:链表题目:奇偶链表 - 图52#card=math&code=O%281%29&id=xljUw)。