奇偶链表问题

奇偶,链表,问题 · 浏览次数 : 25

小编点评

```python class ListNode: def __init__(self, val=0, next=None, prev=None): self.val = val self.next = next self.prev = prev def oddEvenList(head): oddStart, oddEnd, evenStart, evenEnd = None, None, None, None count = 1 cur = head while cur: if (count & 1) == 1: if oddStart is None: oddStart = cur else: oddEnd.next = cur oddEnd = cur else: if evenStart is None: evenStart = cur else: evenEnd.next = cur evenEnd = cur count += 1 cur = cur.next if evenEnd: evenEnd.next = oddStart return oddStart ``` **代码解释:** 1. 使用四个指针 `oddStart`、`oddEnd`、`evenStart` 和 `evenEnd` 来记录奇数链表和偶数链表。 2. 遍历链表,并根据奇偶性构造链表。 3. 如果当前节点是奇数,则将 `oddStart` 指向当前节点,否则将 `oddEnd` 指向当前节点。 4. 如果当前节点是偶数,则将 `evenStart` 指向当前节点,否则将 `evenEnd` 指向当前节点。 5. 最后,将 `oddStart` 和 `evenStart` 的下一个指针指向 `oddEnd` 和 `evenEnd` 的前一个节点,即可构建最终的链表。 **时间复杂度:O(n),其中 n 是链表的长度。** 这是因为我们只遍历链表一次,并使用四个指针来记录奇偶链表和偶数链表的信息。

正文

奇偶链表问题

作者:Grey

原文地址:

博客园:奇偶链表问题

CSDN:奇偶链表问题

题目描述

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。

你的算法的空间复杂度应为 O(1),

时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL

输出: 1->3->5->2->4->NULL

示例 2:

输入: 2->1->3->5->6->4->7->NULL

输出: 2->3->6->7->1->5->4->NULL

说明: 应当保持奇数节点和偶数节点的相对顺序。

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

题目链接

主要思路

如果用辅助数组来做,非常简单,但是不满足题目的要求,因为题目要求空间复杂度 O(1),意味着不能额外申请辅助数组,换一个思路,考虑用一个整型变量来记录遍历的位置是奇数还是偶数,然后用四个指针分别记录当前奇数链表的开头,结尾;偶数链表的开头和结尾,最后把两个链表串联起来即可,所以,只需要设置五个变量即可完成整个算法。

// 奇数链表的开头节点
ListNode oddStart = null;
// 奇数链表的结尾节点
ListNode oddEnd = null;
// 偶数链表的开头节点
ListNode evenStart = null;
// 偶数链表的结尾节点
ListNode evenEnd = null;
// 当前遍历到的节点
ListNode cur = head;
// 当前遍历到的位置,根据题目意思,从 1 开始
int count = 1;

整个流程如下,遍历 cur 指针,同步记录 count,如果 count 记录的位置是奇数, 则构造奇数链表,如果 count 位置记录的是偶数,则构造偶数链表。

构造的过程也比较简单,以构造奇数链表为例:

如果 oddStart 变量为空,则说明奇数链表未初始化,则直接初始化

oddStart = cur;
oddEnd = cur;

奇数链表的头尾指针都指向 cur,说明初始化完成;

否则,说明奇数链表已经初始化过,则把奇数链表的尾部的 next 直接连上 cur,然后把奇数链表的尾部指针指向 cur,即

oddEnd.next = cur;
oddEnd = cur;

构造偶数链表的过程和构造奇数链表的过程同理,不赘述。

构造好两个链表以后,把两个链表连接起来即可,连接的逻辑如下:

如果偶数链表尾部不为空,则奇数链表一定不为空,且偶数链表的尾部就是变换后链表的尾部,即

        if (evenEnd != null) {
            evenEnd.next = null;
        }

最后,要把奇数链表尾部的 next 连接上偶数链表的头部

oddEnd.next = evenStart;

完整代码如下

class Solution {
    // 奇数节点和偶数节点放在一起
    // 所有偶数下标的数一定要在奇数下标数之后(注意:是下标而非值)
    public static ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }
        ListNode oddStart = null;
        ListNode oddEnd = null;
        ListNode evenStart = null;
        ListNode evenEnd = null;
        ListNode cur = head;
        int count = 1;
        while (cur != null) {
            if ((count & 1) == 1) {
                // 奇数
                if (oddStart == null) {
                    oddStart = cur;
                } else {
                    oddEnd.next = cur;
                }
                oddEnd = cur;
            } else {
                // 偶数
                if (evenStart == null) {
                    evenStart = cur;
                } else {
                    evenEnd.next = cur;
                }
                evenEnd = cur;
            }
            count++;
            cur = cur.next;
        }
        if (evenEnd != null) {
            evenEnd.next = null;
        }
        oddEnd.next = evenStart;
        return oddStart;
    }
}

更多

算法和数据结构笔记

与奇偶链表问题相似的内容:

奇偶链表问题

奇偶链表问题 作者:Grey 原文地址: 博客园:奇偶链表问题 CSDN:奇偶链表问题 题目描述 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。 请尝试使用原地算法完成。 你的算法的空间复杂度应为 O(1),

[转帖]-O1,-O2,-O3编译优化知多少

1.从.c文件到可执行文件,其间经历了几步? 高级语言是偏向人,按照人的思维方式设计的,机器对这些可是莫名奇妙,不知所谓。那从高级语言是如何过渡到机器语言的呢?这可是一个漫长的旅途呀! 其中,得经历这样的历程:C源程序->编译预处理->编译->汇编程序->链接程序->可执行文件 1.预处理 读取c源

CF1834

# CF1834 > Virtual Contest 做了 5 道题,非常不错。 ## A.Unit Array 秒切题,判断个数,然后判断一下奇偶即可。 提交: ## B.Maximum Strength ### 题目描述 每一种材料的力量由一个十进制整数表示。 对于一个武器,由**两种**材料构

奇葩需求记录 各个系统取数据联表展示

首先,我刚进公司没多长时间,然后介绍一下背景,这边是个工厂,上了很多个系统搞信息化,这边是有自己的研发团队的(C#),还做了一套系统出来搞生产管理。为了实现信息化呢,这边叫了很多个外包团队开发很多个系统,有些系统语言也不一样(java,C#,我甚至看到了jsp,不过也有springcloud),数据

【转帖】奇淫技巧 | route命令设置网络优先级

奇淫技巧 | route命令设置网络优先级 https://blog.csdn.net/DynmicResource/article/details/120134745 1. 背景 在生活中的会经常遇见一台PC同时连接多个网络的场景.最典型的,一台笔记本可以同时连接一个无线网(手机热点)和一个有线网

数据包的奇妙旅程:揭秘网络传输的7个关键步骤

在发送数据包的过程中,不同层次的网络协议扮演着不同的角色。数据包在经过多层封装后,通过网络设备和路由器进行转发,并最终到达目标设备。在每个层次中,都会进行相应的处理和解封装,以确保数据包能够正确传输和被接收端处理。整个过程涉及到了物理层、数据链路层、网络层、传输层和应用层等多个层次的协议和设备。尽管在简化的示例中,发送数据包的过程相对简单,但实际情况中会更加复杂,需要通过路由表选择最佳路径来保证数据包的快速、高效传输。整个过程展示了网络分层结构的重要性和协同工作的复杂性。

端口占用,无法通过netstat找到进程,占用的端口又不能修改,该怎么办?

最近遇到一个奇葩的问题,项目跑的好好的,没有安装其它特殊软件,突然服务器启动报错,日志如下,显然是服务器的8080端口占用了。 Caused by: java.net.BindException: Address already in use: bind at sun.nio.ch.Net.bind

JavaScript 中 toString 的奇妙使用

JavaScript 中的toString()方法,我们通常会一些其他类型的变量,转为字符串类型。但这里还有一些其他奇妙的用法。 不同的类型调用 toString() 会得到不同的结果。我们来一一分析下。 1. 函数类型 我们开发者自定义的函数,和 JavaScript 官方内置的函数,在调用 to

xHook 源码解析

xHook 是爱奇艺开源的一个PLT Hook 框架 项目地址: https://github.com/iqiyi/xHook 该项目实现了 PTL/GOT Hook PTL hook 的本质是修改内存中,PLT表对应的值,来实现跳转到自定义函数的 .got和.plt它们的具体含义。 The Glo

探究: 编程和英语试卷的奇妙关系

* 很多时候,专业的计算机人士在讨论计算机问题的时候,总在讨论这个实现的原理是什么,这个如何实现,如何更好地实现,如果榨干计算机硬件的性能来实现某个功能活着需求,但是,对于跨学科,跨领域的问题,却很少讨论和涉及,如果你问他们,他们多半会敷衍的回答,没有这样的需求,没有这样的场景. * 其实计算机本身