LeetCode C++ 328. Odd Even Linked List【Linked List】中等

该博客讨论了一种算法,用于重新组织单链表中的节点,使得奇数编号的节点依次排列,偶数编号的节点紧跟其后。算法采用原地操作,空间复杂度为O(1),时间复杂度为O(n)。提供了两种解决方案,一种使用虚拟头结点和for循环,另一种不使用虚拟头结点,直接通过指针操作实现。虽然第二种方法运行时间稍长,但代码更简洁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.

You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.

Example 1:

Input: 1->2->3->4->5->NULL
Output: 1->3->5->2->4->NULL

Example 2:

Input: 2->1->3->5->6->4->7->NULL
Output: 2->3->6->7->1->5->4->NULL

Constraints:

  • The relative order inside both the even and odd groups should remain as it was in the input.
  • The first node is considered odd, the second node even and so on …
  • The length of the linked list is between [0, 10^4] .

题意:给定一个单链表,把所有的奇数编号节点和偶数编号节点分别排在一起。使用原地算法完成,空间复杂度应为 O(1)O(1)O(1) ,时间复杂度应为 O(n)O(n)O(n)nnn 为节点总数。


解法 顺序遍历

使用两个虚拟头结点,分别代表奇数编号链表的头部和偶数编号链表的头部,然后是两个用来进行尾插法的指针;同时使用 for 循环计算编号:

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head == nullptr || head->next == nullptr) return head;
        ListNode edum(0), odum(0); //两个虚拟头结点,便于管理
        ListNode *ep = &edum, *op = &odum; //用于尾部插入
        ListNode *cur = head;
        for (int i = 1; cur; ++i) {
            if (i & 1) {
                op->next = cur;
                op = op->next;
            } else {
                ep->next = cur;
                ep = ep->next;
            }
            cur = cur->next;
        }
        op->next = ep->next = nullptr; //断掉可能的连接
        op->next = edum.next;
        return odum.next;
    }
};

提交后效率如下:

执行用时:16 ms, 在所有 C++ 提交中击败了77.66% 的用户
内存消耗:10.8 MB, 在所有 C++ 提交中击败了5.16% 的用户

不使用虚拟头结点和 for 循环,更加简洁而清晰的代码如下:

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head == nullptr || head->next == nullptr) return head; 
        ListNode *e = head->next; //head为奇数编号链表首结点, e为偶数编号链表头结点
        ListNode *p = head, *q = head->next; //p为奇数编号链表尾结点,q为偶数编号链表尾结点
        while (p->next && q->next) { //p存在但p->next不存在时退出,此时q为空结点(1->2->3); p->next存在但q->next不存在时退出(1->2->3->4),此时q非空结点
            p->next = q->next; //q->next存在
            p = p->next;       //所以p也存在
            q->next = p->next; //此时p->next不一定存在
            q = q->next;       
        }
        p->next = e; //奇数编号链表尾部后+偶数编号链表
        return head; 
    }
};

提交后运行结果如下:

执行用时:20 ms, 在所有 C++ 提交中击败了45.44% 的用户
内存消耗:10.7 MB, 在所有 C++ 提交中击败了9.36% 的用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

memcpy0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值