草庐IT

【牛客网面试必刷TOP101】链表篇(三)

命由己造~ 2023-11-05 原文

链表

一、前言

链表是数据结构中重要的一个章节,他的重要性也不言而喻,在未来不管是笔试还是面试都会遇到这类的题目,所以接下来我就会把一些链表的常考的题目全部整理出来供大家学习指正。


二、学习刷题网站

点击下面链接即可进行刷题学习
开始刷题

三、刷题

先说明一下一些题目取自牛客网面试必刷TOP101
里面的一些题目在我以前的文章详细写到过,如果没有用新的方法就不会再做讲解
链表题目(一)
链表题目(二)
环状链表

<1>单链表的排序

题目链接

描述:

给定一个节点数为n的无序单链表,对其按升序排序。
数据范围:0<n≤100000
要求:时间复杂度 O(nlogn)

示例1

输入:{1,3,2,4,5}
返回值:{1,2,3,4,5}

示例2

输入:{-1,0,-2}
返回值:{-2,-1,0}

思路分析:

①模拟数组

把每个节点的地址放到数组中,然后在数组中对他们的值进行排序,最后在重新构建链表。

int cmp(struct ListNode** e1, struct ListNode** e2)
{
    return (*e1)->val - (*e2)->val;
}

struct ListNode* sortInList(struct ListNode* head ) {
    if(head == NULL)
    {
        return NULL;
    }
    struct ListNode* nums[100000];
    int count = 0;
    struct ListNode* cur = head;
    while(cur)
    {
        nums[count++] = cur;
        cur = cur->next;
    }
    qsort(nums, count, sizeof(struct ListNode*), cmp);
    head = nums[0];
    cur = head;
    for(int i = 1; i < count; i++)
    {
        cur->next = nums[i];
        cur = cur->next;
    }
    cur->next = NULL;
    return head;
}

②归并排序

前面我们做过合并两个有序链表,那我们这个题也可以用这种思路,从中间节点的前一个节点断开,合并两个链表,那么怎么分成两个链表呢,得用到三个指针:

前面我们写过找到中间节点的题目,就是快慢指针,现在我们要找到中间节点的前一个,那么就让slow和fast指针都先走一次,mid就在他们的中间,fast走到尾即可。

奇数情况:

偶数情况:

但是我们拆分完以后发现两个链表不一定为有序的,这时候就要用到归并思想:

如果我们把链表分成单个的节点,那么每个节点都是有序的,然后就可以用合并两个有序链表的方法,怎么把链表分成单个节点呢?答案是递归,如此一来每次要排序的都是有序链表。

对于递归排序在以前的文章里有过详细讲解:
八大排序,你都掌握了吗?

//合并两个有序链表
struct ListNode* _sortInList(struct ListNode* n1, struct ListNode* n2)
{
    if(n1 == NULL)
    {
        return n2;
    }
    if(n2 == NULL)
    {
        return n1;
    }
    struct ListNode* head;
    //小的值链接到下一个
    if(n1->val < n2->val)
    {
        head = n1;
        head->next= _sortInList(n1->next, n2);
    }
    else
    {
        head = n2;
        head->next= _sortInList(n1, n2->next);
    }
    return head;
}

struct ListNode* sortInList(struct ListNode* head ) {
    if(head == NULL || head->next == NULL)
    {
        return head;
    }
    struct ListNode* slow = head, *mid = head->next, *fast = head->next->next;
    while(fast && fast->next)
    {
        slow = slow->next;
        mid = mid->next;
        fast = fast->next->next;
    }
    slow->next = NULL;
    struct ListNode* node1 = sortInList(head);
    struct ListNode* node2 = sortInList(mid);
    struct ListNode* new = _sortInList(node1, node2);
    return new;
}

<2>链表的奇偶重排

题目链接

描述

给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。
注意是节点的编号而非节点的数值。
数据范围:节点数量满足 0 ≤ n ≤ 10^5,节点中的值都满足0≤val≤1000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

示例1

输入:{1,2,3,4,5,6}
返回值:{1,3,5,2,4,6}
说明:
1->2->3->4->5->6->NULL
重排后为
1->3->5->2->4->6->NULL

示例2

输入:{1,4,6,3,7}
返回值:{1,6,7,4,3}
说明:
1->4->6->3->7->NULL
重排后为
1->6->7->4->3->NULL
奇数位节点有1,6,7,偶数位节点有4,3。重排后为1,6,7,4,3

备注:
链表长度不大于200000。每个数范围均在int内。

思路分析:

双指针

我们可以利用两个指针,把奇数节点串成一个链表,偶数位串成一个链表,最后再把两个链表相连接。
这里最重要的是条件判断,一定要画图!!!
我们可以只判断偶数节点和偶数节点的下一位不为空,那么一定可以达成条件:

这是有奇数个节点的情况,结尾自动链接到NULL,如果是偶数个节点,就是以cur->next == NULL为结束标志,那么他的结尾也是自动为NULL。

struct ListNode* oddEvenList(struct ListNode* head ) {
    //如果链表为空,不用重排
        if(head == NULL)
            return head;
        //cur开头指向第二个节点,可能为空
        struct ListNode* cur = head->next;
        //prev开头指向第一个节点
        struct ListNode* prev = head;
        //指向cur开头
        struct ListNode* evenhead = cur;
        while(cur != NULL && cur->next != NULL){
            //偶数节点链接
            prev->next = cur->next;
            prev = prev->next;
            //奇数节点链接
            cur->next = prev->next;
            cur = cur->next;
        }
        //奇偶链表相连
        prev->next = evenhead;
        return head;
}

三、小结

在做题前一定要先画好图,尽量想好特殊情况,考虑好结束条件。
链表篇就到此结束,接下来博主会更新更多的题目

点击链接一起刷题吧



有关【牛客网面试必刷TOP101】链表篇(三)的更多相关文章

  1. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  2. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

  3. 西安华为OD面试体验 - 2

    西安华为OD面试体验开始投简历技术面试进展工作进展开始投简历去年一整年一直在考研和工作之间纠结,感觉自己的状态好像当时的疫情一样差劲。之前刚毕业的时候投了个大厂的简历,结果一面写算法的时候太拉跨了,虽然知道时dfs但是代码熟练度不够,放在平时给足时间自己可以调试通过,但是熟练度不够那面试当时就写不出来被刷了。说真的算法学到后期我感觉最重要的是熟练度和背板子(对于我这种普通玩家来说),面试题如果一上来短时间内想不出思路就完蛋了。然后由于当时找的工作不是很理想就又想考研了。但是考研是有风险的,我自我感觉自己可能冲不上那个学校,而找工作一个没成可以继续找嘛。本着抱着试试看的态度在boss上投了简历,

  4. ruby-on-rails - rails 生成 rspec :install config/environments/development. rb:1:in `<top (required)>': 未定义方法 `configure' - 2

    首先,这是我的版本:Greg-Nowickis-MacBook-Pro:sample_appGreg_Nowicki$ruby-vruby2.0.0p451(2014-02-24revision45167)[x86_64-darwin13.1.0]Greg-Nowickis-MacBook-Pro:sample_appGreg_Nowicki$rails-vRails4.0.4我正在学习HartlRails教程并安装rspec进行测试。我已将gem'rspec-rails'添加到我的gemfile中,当我运行railsgeneraterspec:install时,这就是我得到的:Gre

  5. [面试直通版]操作系统核心之进程、线程与协程(下) - 2

    点击->操作系统复习的文章集目录操作系统线程线程是什么进程与线程的关系用户态/内核态操作系统资源管理内核态用户态内核态/用户态切换程序运行类型分析计算密集型IO密集型结合进程,线程来理解程序运行类型分析协程基础上下文切换协程协程为什么叫协作式线程?协程的优缺点操作系统线程典型问题:简述进程和线程的区别以下内容带您一步步了解线程是什么比进程更小的独立运行的基本单位-线程(Threads)线程的提出主要是为了提高系统内程序并发执行的程度,从而进一步提升系统的吞吐量,充分发挥多核CPU的优越性而设计的引入进程是为了操作系统更加方便地管理程序,使得多个程序能并发管理和执行而线程则是为了减少程序在并发执

  6. 【华为OD技术面试 | 真八股 】MySQL联合索引,谈springIOC的理解,谈springAOP的理解,Erika和zookeeper等问题 - 2

    文章目录华为OD面试流程1.mysql数据库建了两个字段,且设置了联合索引,如果其中有一个字段为空会出现什么问题?2.谈谈springIOC的理解,有什么好处,解决了什么问题3.谈谈springAOP的理解,切面编程有没有实际应用,有哪些注解,作用是什么,有那些应用场景?4.Erika和zookeeper有了解过吗,作用是什么,主要解决了什么问题5.谈谈JDK、JRE、JVM的理解,区别是什么6.谈谈对泛型的理解7.JVM的组成华为OD面试流程机试:三道算法题,关于机试,橡皮擦已经准备好了各语言专栏,可以直接订阅。性格测试:机试技术一面(本专栏核心)技术二面(本专栏核心)主管面试定级定薪发of

  7. 【数据结构和算法】实现带头双向循环链表(最复杂的链表) - 2

    前文,我们实现了认识了链表这一结构,并实现了无头单向非循环链表,接下来我们实现另一种常用的链表结构,带头双向循环链表。如有仍不了解单向链表的,请看这一篇文章(7条消息)【数据结构和算法】认识线性表中的链表,并实现单向链表_小王学代码的博客-CSDN博客目录前言一、带头双向循环链表是什么?二、实现带头双向循环链表1.结构体和要实现函数2.初始化和打印链表3.头插和尾插4.头删和尾删5.查找和返回结点个数6.在pos位置之前插入结点7.删除指定pos结点8.摧毁链表三、完整代码1.DSLinkList.h2.DSLinkList.c3.test.c总结前言带头双向循环链表,是链表中最为复杂的一种结

  8. ruby-on-rails - { "error": { "message": "Missing client_id parameter.", "type": "OAuthException", "code": 101 } } - 2

    我正在关注RyanBatesScreenCast#360Facebook身份验证...当我到达点击链接登录facebook的部分时,我得到一个{"error":{"message":"Missingclient_idparameter.","type":"OAuthException","code":101}}我尝试像之前所说的那样重新启动服务器我正在拔头发试图弄清楚这一点我在facebook开发页面上的网站url是正确的我已经按照他的步骤数百次 最佳答案 可能是你没有为FACEBOOK_KEY和FACEBOOK_SECRET设置e

  9. 相机面试问题总结 - 2

    1,Camera基本工作原理答案:光线通过镜头Lens进入摄像头内部,然后经过IRFilter过滤红外光,最后到达sensor(传感器),senor分为按照材质可以分为CMOS和CCD两种,可以将光学信号转换为电信号,再通过内部的ADC电路转换为数字信号,然后传输给DSP(如果有的话,如果没有则以DVP的方式传送数据到基带芯片baseband,此时的数据格式RawData,后面有讲进行加工)加工处理,转换成RGB、YUV等格式输出。数据流是如何从sensor到APP的?上述描述结束后,在ISP处理后面的阶段,数据会进行分流,分为capture,preview,video等以供后续动作使用。例如

  10. ruby-on-rails - 如何在一个周末准备 Ruby 面试 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。我是一名经验丰富的网络开发人员,但只有一点点Ruby/Rails经验。我周一刚在一家Ruby商店接受面试,他们确实意识到我没有太多Ruby经验。除了我手边的2或3本Ruby书籍外,我还可以利用哪些其他资源来参加周末的Ruby速成类。顺便说一下,我在hostingrails上确实有一个最低限度的帐户,尽管我从未使用过它。我没有看到任何其他与搜索“rubyi

随机推荐