leetcode328. 奇偶链表,附详细解析和代码注释

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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cider瞳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值