【数据结构】面试OJ题——链表

 

目录

1.移除链表元素

思路:

 2.反转链表

思路:

3.链表的中间结点

思路:

 4.链表中的倒数第K个结点

 思路:

 5.合并两个有序链表

 思路:

 6.链表分割

思路:

7.链表的回文结构

思路:

 8.随机链表的复制

 思路:


1.移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

思路:

 定义新链表的头结点和尾结点,循环遍历原链表即可,遇到复合的结点删除即可;

最后将尾结点的next置空。

因为这里并没有使用哨兵位,所以第一次插入的时候,要特殊处理

struct ListNode* removeElements(struct ListNode* head, int val) {
    
    struct ListNode* newnode = NULL,*tail = NULL;
    struct ListNode* cur = head;
    
    while(cur)
    {
        //
        if(cur->val != val)
        {
            //空,尾插
            if(tail == NULL)
            {
                newnode = tail = cur;
            }
            else
            {
                tail->next = cur;
                tail = tail->next;
            }
            cur = cur->next;
        }
        else
        {
            struct ListNode* tmp = cur;
            cur = cur->next;
            free(tmp);
            tmp = NULL;
        }
    }
    if(tail)
    tail->next = NULL;

    return newnode;
}

 2.反转链表

206. 反转链表 - 力扣(LeetCode)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

思路:

 定义三指针,当前位置,上一个位置,下一个位置;

将结点next链接到上一个结点即可,然后将下一个位置赋给当前指针;

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* cur = head;
    struct ListNode* prev = NULL;
    while(cur)
    {
        struct ListNode* next = cur->next;

        cur->next = prev;
        prev = cur;
        cur = next;
    }    
    return prev;
}

3.链表的中间结点

 876. 链表的中间结点 - 力扣(LeetCode)

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

 

思路:

使用快慢指针方式,快指针走两步,慢指针走一步,可以发现当快指针为NULL  或者快指针的下一个为空的时候 slow是中间结点 

struct ListNode* middleNode(struct ListNode* head) {
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        //快指针走两步,慢指针走一步
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

 4.链表中的倒数第K个结点

链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

输入一个链表,输出该链表中倒数第k个结点。

 思路:

一般链表问题,使用最多的解决方式就是快慢指针,这个题目和第三题相似很多;

先让快指针走K步,然后两指针同时走;

注:这里的快指针和慢指针一起走 是一步步走;同时,防止快指针走K步越界了,

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    //快慢指针
    struct ListNode* fast = pListHead;
    struct ListNode* slow = pListHead;

    //快指针先走k步
    while(k--)
    {
        if(fast == NULL)
        return NULL;
        fast = fast->next;
    }

    //同时走
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

 5.合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

 思路:

合并两个链表按照大小顺序排列,尾插小的结点;

第一次:将走完链表其中一条,注意并没有定义哨兵位,所以第一次插入特殊处理

第二次:将没走完的链表直接尾插到新链表后即可;

将小的结点尾插到新链表中

 

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode* newnode = NULL,*tail = NULL;
    
    if(list1 == NULL)
    return list2;
    if(list2 == NULL)
    return list1;
    while(list1 && list2)
    {
        if(list1->val < list2->val)
        {
            if(newnode == NULL)
            {
                newnode = tail = list1;
            }
            else
            {
                tail->next = list1;
                tail = tail->next;
            }
                list1 = list1->next;
        }
        //list2
        else
        {
            if(newnode == NULL)
            {
                 newnode = tail = list2;
            }
            else
            {
                tail->next = list2;
                tail = tail->next;
            }
                list2 = list2->next;
        }
    }
    if(list1)
    tail->next = list1;
    if(list2)
    tail->next = list2;
    return newnode;
}

 6.链表分割

链表分割_牛客题霸_牛客网 (nowcoder.com)

现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

 

思路:

对于链表分割最好用带头哨兵位的链表来解决,减化了两条链表的链接问题;如果不用哨兵位,要增加很多特殊处理判断;

有了哨兵位,在链接两条链表时,直接链接即可,尾部置NULL;

 ListNode* partition(ListNode* phead, int x) {
        struct ListNode* cur = phead;
        struct ListNode* list1,*tail1,*list2,*tail2;

        //哨兵位
       list1 = tail1= (struct ListNode*)malloc(sizeof(struct ListNode));
       list2 = tail2= (struct ListNode*)malloc(sizeof(struct ListNode));

       while(cur)
       {
            if(cur->val < x)    //小于x
            {
                tail1->next = cur;
                tail1 = tail1->next;
            }
            else    //大于等于x
            {
                tail2->next = cur;
                tail2 = tail2->next;
            }
            cur = cur->next;
       }
       tail1->next = list2->next;   //链接两条链表
       tail2->next = NULL;  //尾部置NULL
       
       phead = list1->next;
       free(list1);
       free(list2);
       return phead;
    }

7.链表的回文结构

 链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

思路:

1.先用快慢指针找到中间结点

2.反转中间节点后的链表

3.是否为回文判断

 bool chkPalindrome(ListNode* head) {
        //快慢指针找到中间节点
        struct ListNode* slow = head,*fast = head;
        while(fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        //此刻slow 是中间节点
        //反转mid后的链表
        struct ListNode* mid = slow;   
        struct ListNode* cur = mid;
        struct ListNode* newnode = NULL;
        while(cur)
        {
             struct ListNode* next = cur->next;
             cur->next = newnode;
             newnode = cur;
             cur = next;
        }

        //回文比较
        struct ListNode* phead = head;
        while(phead && newnode)
        {
            if(phead->val != newnode->val)
                return false;

            phead = phead->next;
            newnode = newnode->next;
        }
        return true;
    }

 8.随机链表的复制

138. 随机链表的复制 - 力扣(LeetCode)

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

 

 思路:

1.先复制一条没有random的新链表,每个节点尾插到对应结点后面

2.添加random,可以发现,复制的结点的上一个结点的random就是该结点需要的random

3.将添加后的链表尾插到新链表中,记得跳过原链表的结点

 

 

struct Node* copyRandomList(struct Node* head) {
    struct Node* cur = head;
    
    while(cur)
    {
        struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
        newnode->val = cur->val;
        newnode->next = cur->next;
        cur->next = newnode;

        cur = cur->next->next;
    }
    //添加random
    cur = head;
    while(cur)
    {
        struct Node* copy =cur->next;

        //原链表 random为空情况
        if(cur->random == NULL)
        {
        copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }
            cur = cur->next->next;
    }
    //尾插
     cur = head;
     struct Node* newnode = NULL,*tail = NULL;
    while(cur)
    {
        struct Node* copy =cur->next;
         struct Node* next = copy->next;;

         if(tail == NULL)
         {
            newnode = tail = copy;
         }
        else
         {
             tail->next = copy;
             tail = tail->next;
        }
        cur->next = next;
        cur = next;
    }
    return newnode;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/237145.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

区块链扩容问题研究【06】

1.Plasma&#xff1a;Plasma 是一种基于以太坊区块链的 Layer2 扩容方案&#xff0c;它通过建立一个分层结构的区块链网络&#xff0c;将大量的交易放到子链上进行处理&#xff0c;从而提高了以太坊的吞吐量。Plasma 还可以通过智能合约实现跨链交易&#xff0c;使得不同的区块…

【基础篇】一,认识STM32

一&#xff0c;什么是STM32&#xff1f; STM32是一款由意法半导体公司开发的32位微控制器&#xff1b;其中ST指意法半导体&#xff1b;M指MCU或MPU&#xff0c;32指32 位。 STM32覆盖了Cortex-M的多种系列&#xff0c;包括M0、M0、M3、M7等。在分类上&#xff0c;STM32有很多…

数据在内存中的存储(整型篇)

1.辨析原码反码补码&#xff1a; 1.原码&#xff1a;有32位&#xff08;int类四个字节&#xff0c;一个字节八个比特位&#xff09;&#xff0c;第一位是符号位&#xff0c;0正1负&#xff0c;其余为二进制位。 2.计算一般是对原码进行计算&#xff0c;但在负数计算使用原码会导…

视频中自监督学习:「我的世界」下指令理解与跟随

本文介绍了北京大学人工智能研究院梁一韬助理教授所带领的 CraftJarvis 团队在「我的世界」环境下探索通用智能体设计的新进展&#xff0c;题为“GROOT: Learning to Follow Instructions by Watching Gameplay Videos”。 ​ GROOT 该研究的核心目标是探索能否摆脱文本数据的标…

【LLM】大模型之RLHF和替代方法(DPO、RAILF、ReST等)

note SFT使用交叉熵损失函数&#xff0c;目标是调整参数使模型输出与标准答案一致&#xff0c;不能从整体把控output质量&#xff0c;RLHF&#xff08;分为奖励模型训练、近端策略优化两个步骤&#xff09;则是将output作为一个整体考虑&#xff0c;优化目标是使模型生成高质量…

SpringBoot集成系列--RabbitMQ

文章目录 一、代码1、添加依赖2、配置RabbitMQ连接3、RabbitMQ配置4、创建生产者5、创建消费者6、测试 二、遇到的问题1、Channel shutdown2、收不到信息3、安装RabbitMQ&#xff0c;无法访问控制台访问 一、代码 1、添加依赖 在pom.xml文件中添加RabbitMQ的相关依赖 <de…

python期末简答题及答案,python期末题库和答案

本篇文章给大家谈谈python期末简答题及答案&#xff0c;以及python期末题库和答案&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 期末复习判断题 &#xff08; √ &#xff09;Python变量名区分大小写,所以student和Student不是同一个变量。&#xff08; &…

MySQL慢SQL优化思路

MySQL慢SQL优化思路 具体思路&#xff1a; 1、慢查询日志记录慢 SQL 2、explain 分析 SQL 的执行计划 3、profile 分析执行耗时 4、Optimizer Trace 分析详情 5、确定问题并采用相应的措施 1、查看慢日志 1.1 使用命令查询慢日志配置 mysql> show variables like s…

机器人制作开源方案 | 网球收纳机器人

作者&#xff1a;孙宇晗、刘子昊、单正扬、李悦、张紫琦 单位&#xff1a;山东大学&#xff08;威海&#xff09; 指导老师&#xff1a;庞豹 1. 场景调研 1.1 宏观背景 体育作为社会经济、政治、文化的重要组成部分,越来越受政府、社会、学校等各阶层的关注。近年来&#x…

数据结构与算法-Rust 版读书笔记-2线性数据结构-栈

数据结构与算法-Rust 版读书笔记-2线性数据结构-栈 一、线性数据结构概念 数组、栈、队列、双端队列、链表这类数据结构都是保存数据的容器&#xff0c;数据项之间的顺序由添加或删除时的顺序决定&#xff0c;数据项一旦被添加&#xff0c;其相对于前后元素就会一直保持位置不…

[ABAP] Selection Screen 按钮管理

1. 隐藏执行按钮 initialization.data btab type table of sy-ucomm.append ONLI to btab.call function RS_SET_SELSCREEN_STATUSexportingp_status sy-pfkeytablesp_exclude btab.2.添加按钮(Tool Bar) tables: sscrfields.selection-screen begin of line.selection-scre…

Leetcode704二分查找、折半查找(Java实现)

好久没有更新算法题&#xff0c;今天来写一道二分查找的题目。题目要求如下&#xff0c; 那么这道题的解题思路如下&#xff0c;我们寻找的过程是首先去访问数组的中间位置mid&#xff0c;如果nums[mid]大于了targe那么说明&#xff0c;我们要找的数在mid的左半边&#xff0c;…

外包干了3个月,技术退步明显。。。

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

awt中文乱码-Intellij IDEA

乱码的根本原因在于秦始皇嘎太早了&#xff08;bushi 解决方法&#xff1a;肉眼可见的编码设置统一为GBK 1.打开设置找到文件编码 2.肉眼可见的编码统统改成GBK 有人该问了&#xff0c;为什么不改成utf-8&#xff0c;因为awt的编码由操作系统决定&#xff0c;我的是win家庭中…

Faster R-CNN

Faster R-CNN是作者Ross Girshick继Fast R-CNN后的又一力作。同样使用VGG16作推理速度在GPU上达到5fps(包括候选区域的生成)&#xff0c;准确率为网络的backbone&#xff0c;也有进一步的提升。在2015年的ILSVRC以及COCO竞赛中获得多个项目的第一名。 算法流程 右边这部分和Fa…

人体关键点检测3:Android实现人体关键点检测(人体姿势估计)含源码 可实时检测

目录 1. 前言 2.人体关键点检测方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下而上)方法&#xff1a; 3.人体关键点检测模型训练 4.人体关键点检测模型Android部署 &#xff08;1&#xff09; 将Pytorch模型转换ONNX模型 &#xff08;2&#xff09; 将ONNX模型转换…

(纯原创)基于JavaWeb的宠物领养商城(详细源码以及开发设计报告)

摘要 本宠物领养系统以MVC分层为原则&#xff0c;数据持久化使用Mybatis&#xff0c;数据库使用MySQL&#xff0c;这些技术目前相对比较成熟&#xff0c;方便系统的维护与扩展 商城系统包括了宠物领养、用户注册、用户登录、商品查询、商品添加到购物车、删除商品等几大功能…

云贝教育 | 分享课:12月12日周二晚Oracle分享课享来了

Oracle 19c OCM分享课分享主题: Introduction to Clusterware 讲师&#xff1a;郭一军 直播分享平台&#xff1a;云贝教育视频号 时间&#xff1a;12月12日 周二晚 19: 30

广东佛山开房屋租赁发票

我是20223年12月办理的&#xff0c;给大家做个参考。 一、准备材料 &#xff08;如果非房东本人办理&#xff0c;还需要房东签份授权书&#xff0c;多复印几份或者直接签多份&#xff0c;不然会被税务局收走&#xff09; 废话不多说&#xff0c;直接上图。 二、线上预约 附个…

H264帧内预测介绍

4x4 luma宏块的预测模式 4x4 luma宏块有9种预测模式 16x16 luma宏块的预测模式 16 x16 luma宏块有四种预测模式 帧内预测模式信令(Signalling intra prediction modes) 4x4 或者8x8 luma prediction 对4x4或者8x8 luma因为每一个宏块都要指明预测模式,且有9种预测模式可…