【数据结构】经典单链表OJ题!!

学习完单链表,习题就成了最好的巩固方式

目录

  • 1.链表分割:
    • 思路:
    • 代码实现:
  • 2.随机链表的复制:
    • 思路1:
    • 代码实现:
    • 思路2:
    • 代码实现:
  • 3.环形链表:
    • 3.1环形链表1:
      • 思路:
      • 代码实现:
    • 3.2环形链表2:
      • 思路:
      • 代码实现:

1.链表分割:

在这里插入图片描述
链表分割,链接奉上

思路:

我们可以创建两个newhead
将比x小的尾插放到newhead1
x大的放在newhead2
再将两个链表进行链接

注意:

  • 在进行创建新的链表时,最好使用带有哨兵位的链表,在进行链接时会比较容易,
    因为没有哨兵位的链表需要判断是否两个链表是否为空,并分别做出处理措施

  • 在尾插时,有可能出现如下图的情况在这里插入图片描述
    故我们需要将tail2->next = NULL

代码实现:

class Partition {
public:
    ListNode* partition(ListNode* pHead, int val) {
        //两个哨兵位的创建
        struct ListNode* newhead1 = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* newhead2 = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* tail1 = newhead1;
        struct ListNode* tail2 = newhead2;
        tail1->next = newhead1->next = NULL;
        tail2->next = newhead2->next = NULL;

        while(pHead)
        {
            if(pHead->val < val)
            {
                tail1->next = pHead;
                tail1 = tail1->next;
            }
            else
            {
                tail2->next = pHead;
                tail2 = tail2->next;
            }
            pHead = pHead->next;
        }
        tail1->next = newhead2->next;
        tail2->next = NULL;
        return newhead1->next;
    }
};

2.随机链表的复制:

在这里插入图片描述
链接奉上

思路1:

先复制一份没有进行random处理的copy链表
我们可以根据random的指向的位置原位置
通过计算得出他们之间的距离,
再根据距离进行确定copy链表中random的位置
这样实现,时间复杂度是O(N^2)

代码实现:

理论存在,实践开始

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */
struct Node* creat(int x)
{
    struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
    newnode->val = x;
    newnode->next = NULL;
    return newnode;
}

struct Node* copyRandomList(struct Node* head) 
{
    struct Node* cur = head;
    struct Node* newhead = NULL;
    struct Node* tail = NULL;
    while(cur)
    {
        if(newhead == NULL)
        {
            newhead = creat(cur->val);
            tail = newhead;
        }
        else
        {
            tail->next = creat(cur->val);
            tail = tail->next;
        }
        cur = cur->next;
    }
    int count = 0;
    cur = head;
    struct Node* subcur = newhead;
    while(cur)
    {
        count = 0;
        struct Node* tmp1 = head;
        while(cur->random != tmp1)
        {
            count++;
            tmp1 = tmp1->next;
        }
        struct Node* tmp = newhead;
        while(count--)
        {
            tmp = tmp->next;
        }
        subcur->random = tmp;
        cur = cur->next;
        subcur = subcur->next;
    }
    return newhead;
}

思路2:

在原链表的每一个元素后边插入一个一样元素的copy节点
在这里插入图片描述
之后,我们发现当前节点后的copy节点的random指向当前节点的random的next,仔细咀嚼(可以自己画图感受一下),这句话也是整个代码的核心
最后再将整个链表进行拆解,返回新的结点

代码实现:

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) 
{
    struct Node* cur = head;
    //添加copy节点
    while(cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        struct Node* next = cur->next;
        copy->val = cur->val;
        copy->next = next;
        cur->next = copy;

        cur = next;
    }
    
    cur = head;
    //random的复制
    while(cur)
    {
        if(cur->random == NULL)
        {
            cur->next->random = NULL;
        }
        else
        {
            cur->next->random = cur->random->next;
        }
        cur = cur->next->next;
    }

    //解开节点
    struct Node* newhead = NULL;
    struct Node* tail = NULL;

    cur = head;
    while(cur)
    {
        struct Node* next = cur->next->next;
        if(newhead == NULL)
        {
            newhead = tail = cur->next;
        }
        else
        {
            tail->next = cur->next;
            tail = tail->next;
        }
        cur = next;
    }
    return newhead;
}

3.环形链表:

3.1环形链表1:

在这里插入图片描述
链接奉上

思路:

利用快慢指针,这是解决此问题的最可行办法,
一个走一步,一个走两步,
当有环时,两者都进入环,因为两者固定减少1步,故必然可以相遇,
当没有环时,fast == NULL,或者fast指针->next == NULL

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
        return true;
    }   
    return false;
}

3.2环形链表2:

在这里插入图片描述
链接奉上

思路:

先输出一个结论:
找到快慢指针相遇的点,设置两个指针,一个从头开始走,一个从相遇点开始走,一次一步,相遇点就是环的开始点,我们返回此指针

在这里插入图片描述

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    struct ListNode* cur = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
        {
            struct ListNode* meet = slow;
            while(1)
            {
                if(cur == meet)
                {
                    return meet;
                }
                cur = cur->next;
                meet = meet->next;
            }
        }
    }
    return NULL;
}

若有问题可以及时询问博主

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

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

相关文章

『MySQL快速上手』-⑧-内置函数

文章目录 1.日期函数1.1 获得年月日1.2 获得时分秒1.3 获得时间戳1.4 在日期的基础上加日期1.5 在日期的基础上减去时间1.6 计算两个日期之间相差多少天案例1案例22.字符串函数案例3.数学函数4.其他函数1.日期函数 1.1 获得年月日

【C++】——运算符重载

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

promise多请求并发

<!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title> </head><body><script>let p1 new Promise((resolve, reject) > {resolve(成功了)})let p2 new Promise((resolve, reject) > …

JAVA基础语法编程详解---三目运算符

6.判断体重指数 题目描述 - 描述 体重指数 体重 (kg) / ( 身高 (m) 身高 (m) )&#xff0c;小于18.5属于偏瘦&#xff0c;介于18.5和20.9之间&#xff08;左闭右开&#xff09;属于苗条&#xff0c;介于20.9和24.9之间&#xff08;左闭右闭&#xff09;属于适中&#xff0c;…

云原生之使用Docker部署home-page个人导航页

云原生之使用Docker部署home-page个人导航页 一、home-page个人导航页介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载home-page镜像五、部署home-page导航页5.1 创建挂…

振南技术干货集:深入浅出的Bootloader(3)

注解目录 1、烧录方式的更新迭代 1.1 古老的烧录方式 (怀旧一下&#xff0c;单片机高压烧录器。) 1.2 ISP 与ICP 烧录方式 (还记得当年我们玩过的 AT89S51?) 1.3 更方便的 ISP 烧录方式 1.3.1串口 ISP &#xff08;是 STC 单片机成就了我们&#xff0c;还是我们成就了…

通配符SSL证书

通配符SSL证书是一种特殊的数字证书&#xff0c;用于在互联网上建立安全的连接&#xff0c;其特点是可以保护多个子域名&#xff0c;并且具有很高的兼容性和扩展性。本文将详细介绍通配符SSL证书的相关概念、优点和应用等。 首先&#xff0c;我们需要了解什么是SSL证书。 SSL证…

python入口文件方便在其它目录也能执行

dir_path os.path.dirname(os.path.realpath(__file__)) parent_dir_path os.path.abspath(os.path.join(dir_path, os.pardir)) sys.path.insert(0, parent_dir_path)

CPU vs GPU:谁更适合进行图像处理?

CPU 和 GPU 到底谁更适合进行图像处理呢&#xff1f;相信很多人在日常生活中都会接触到图像处理&#xff0c;比如修图、视频编辑等。那么&#xff0c;让我们一起来看看&#xff0c;在这方面&#xff0c;CPU 和 GPU 到底有什么不同&#xff0c;哪个更胜一筹呢&#xff1f; 一、C…

股市助手:实时股市快讯,真人语音播报,助您第一时间获取最新资讯(自己写的分享给需要的人)

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f3e1; 使用环境 &#x1f3e1;&#x1f4d2; 使用方法 &#x1f4d2;&#x1f4dd; 软件设置&#x1f4dd; 软件运行 &#x1f4d6; 介绍 &#x1f4d6; 给大家分享一款自己写的软件《股市助手》&#xff0c;老规矩&#xff…

【C++初阶(七)】类和对象(下)

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

Linux安装MongoDB

Download MongoDB Community Server | MongoDB 简单安装 百度网盘 链接&#xff1a;https://pan.baidu.com/s/1j7q0TtkpByfg8kqb2UCHZw 提取码&#xff1a;93zr --来自百度网盘超级会员V4的分享 解压文件 tar -xvf mongodb-linux-x86_64-4.0.10.tgz 移动解压后的文件到指…

VS设置--查看引用库源代码

1.工具-->选项-->文本编译器-->C#-->高级-->勾选支持导航到反编译源(试验)

Java系列之 IDEA 为类 和 方法设置注解模板

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 1、类方法注解模板 1、File–>settings–…

虚拟局域网

虚拟局域网(VLAN) VLAN建立于交换技术的基础之上 广播域(broadcast domain)&#xff1a;其中任何一台设备发出的广播通信都能被该部分网络中的所有其他设备所接收&#xff0c;这部分网络就叫广播域利用以太网交换机可以很方便地实现虚拟局域网VLAN(Virtual LAN)对于一个主机和…

Windows安装docker地址流程配截图,附网卡被禁用处理(有线插了没反应)

Windows安装docker流程配截图 Windows安装docker比较简单&#xff0c;跟着步骤一步一步操作就行&#xff0c;安装包到官网下载就行 安装包下载 下载地址 https://www.docker.com/get-started/下载后双击打开&#xff0c;进入安装界面。单选框是添加桌面快捷方式&#xff0c…

产品经理天天跑火车,我直接和他闹翻

前言 说起产品经理与程序员&#xff0c;简直就是一对冤家。 程序员觉得产品经理不尊重技术规则&#xff0c;产品经理埋怨程序员不尊重创作用心。 一边互怼&#xff0c;一边还要合作&#xff0c;终于&#xff0c;有人忍不下去&#xff0c;动手了…… ![](https://img-blog.cs…

【渗透实战】木马免杀

先看效果(文中附源码) 思路 1.shellcode自身免杀 首先cs生成一个bin文件 再没有二开的情况下落地就会死 那么如何处理呢? 可以通过对shellcode进行加密和编码的方式,然后在内存中进行解密执行 这里介绍几种主流的编码和加密方式 编码方式: base64 sgn编码 加密方式: XO…

这 11 个 for 循环优化你得会

日常开发中&#xff0c;经常会遇到一些循环耗时计算的操作&#xff0c;一般也都会采用 for 循环来处理&#xff0c;for 作为编程入门基础&#xff0c;主要是处理重复的计算操作&#xff0c;虽然简单好用&#xff0c;但在写法上也有很多的考究&#xff0c;如果处理不好&#xff…

「Verilog学习笔记」用优先编码器①实现键盘编码电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 用此编码器实现键盘的编码电路。 注意&#xff1a;编码器的输出是低电平有效&#xff0c;而键盘编码电路输出的是正常的8421BCD码&#xff0c;是高电平有效。因此将编…