leetcode328. 奇偶链表
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。
示例 1:
输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]
示例 2:
输入: head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4]
算法的核心思想是通过两个指针 odd 和 even 来分别遍历奇数位和偶数位的节点,然后在遍历的过程中逐步构建新的链表,使得奇数位的节点在偶数位的节点之前。
边界条件检查:首先,函数检查 head 是否为 NULL。如果链表为空(即 head == NULL),则不需要进行任何操作,直接返回 head。
初始化指针:
ListNode* even = head->next; 初始化 even 指针指向第二个节点,即偶数位的第一个节点。
ListNode* odd = head; 初始化 odd 指针指向第一个节点,即奇数位的第一个节点。
ListNode* evenhead = even; 初始化 evenhead 指针,它将用于最后将偶数部分连接到奇数部分的末尾。
链表遍历:使用 while 循环遍历链表,直到 even 或 even->next 为 NULL,即到达链表的末尾或偶数位的最后一个节点。
在循环内部,首先将 odd->next 设置为 even->next,这样 odd 节点就指向了下一个奇数位的节点。
然后将 odd 移动到下一个奇数位。
接着,将 even->next 设置为 odd->next,这样 even 节点就指向了下一个偶数位的节点。
最后,将 even 移动到下一个偶数位。
连接偶数部分:当循环结束时,odd 指针将指向奇数部分的最后一个节点。此时,将 odd->next 设置为 evenhead,即将偶数部分连接到奇数部分的末尾。
返回结果:最后,函数返回 head,即重排后的链表的头节点。
这个算法的时间复杂度是 O(N),其中 N 是链表的长度。这是因为算法只需要遍历链表一次。空间复杂度是 O(1),因为除了输入参数外,算法只使用了有限的额外空间(几个指针变量)。
具体代码如下:
class Solution {public:ListNode* oddEvenList(ListNode* head) {//如果链表为空,不用重排if (head == NULL)return head;//even开头指向第二个节点,可能为空ListNode* even = head->next;//odd开头指向第一个节点ListNode* odd = head;//指向even开头ListNode* evenhead = even;while (even != NULL && even->next != NULL) {//odd连接even的后一个,即奇数位odd->next = even->next;//odd进入后一个奇数位odd = odd->next;//even连接后一个奇数的后一位,即偶数位even->next = odd->next;//even进入后一个偶数位even = even->next;}//even整体接在odd后面odd->next = evenhead;return head;}
};