Featured image of post LeetCode 75系列 - 328. 奇偶链表

LeetCode 75系列 - 328. 奇偶链表

题目描述

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别分组,保持它们原有的相对顺序,然后把偶数索引节点分组连接到奇数索引节点分组之后,返回重新排序的链表。

第一个节点的索引被认为是 奇数第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

示例 1:

img

1
2
输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]

示例 2:

img

1
2
输入: head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4]

提示:

  • n == 链表中的节点数
  • 0 <= n <= 104
  • -106 <= Node.val <= 106

题解

解法一

通过遍历,构造奇偶链表,最终合并两个链表。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        ListNode* odd = new ListNode(-1);
        ListNode* node = odd;
        ListNode* even = new ListNode(-1);
        ListNode* even_head = even;

        int i{1};
        while (head) {
            ListNode* n = new ListNode(head->val);
            if (i % 2 == 0) {
                even->next = n;
                even = even->next;
            } else {
                odd->next = n;
                odd = odd->next;
            }
            head = head->next;
            i++;
        }
        odd->next = even_head->next;
        return node->next;
    }
};

解法二

维护两个指针 odd 和 even 分别指向奇数节点和偶数节点,初始时 odd = head,even = head->next。通过迭代的方式将奇数节点和偶数节点分离成两个链表,每一步首先更新奇数节点,然后更新偶数节点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head == nullptr)
            return nullptr;
            
        ListNode* odd = head;
        ListNode* even = head->next;
        ListNode* even_head = even;

        while (even && even->next) {
            odd->next = even->next;
            odd = odd->next;
            even->next = odd->next;
            even = even->next;
        }
        odd->next = even_head;
        return head;
    }
};