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

news2024/12/29 8:45:08

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

目录

  • 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;
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

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

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

Java项目开发:基于Springboot+vue口腔牙科诊所管理系统

项目介绍 本选题则旨在通过标签分类管理等方式&#xff0c;实现管理员&#xff1a;首页、个人中心、会员管理、病例就诊信息管理、牙齿保健产品管理、复查提醒管理、预约挂号管理、药品信息管理、留言板管理、系统管理、订单管理&#xff0c;会员&#xff1b;首页、个人中心、…

Mozilla 面向基于 Debian 的 Linux 发行版

导读Mozilla 公司今天发布新闻稿&#xff0c;表示面向 Debian、Ubuntu 和 Linux Mint 等基于 Debian 的发行版&#xff0c;推出了.deb 格式的 Firefox Nightly 浏览器安装包&#xff0c;便于用户在上述发行版中更轻松地安装。 本次更新的亮点之一在于采用 APT 存储库&#xff0…

【机器学习基础】机器学习的基本术语

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习 欢迎订阅&#xff01;后面的内容会越来越有意思~ &#x1f4a1;往期推荐&#xff1a; 【机器学习基础】机器学习入门&#xff08;1&#xff09; 【机器学习基…

界面控件DevExpress WPF Splash Screen,让应用启动画面更酷炫!

DevExpress WPF的Splash Screen组件可以为应用程序创建十分酷炫的启动屏幕&#xff0c;提高用户在漫长的启动操作期间的体验&#xff01; P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress …

(八)Spring源码解析:Spring MVC

一、Servlet及上下文的初始化 1.1> DispatcherServlet的初始化 对于Spring MVC来说&#xff0c;最核心的一个类就是DispatcherServlet&#xff0c;它负责请求的行为流转。那么在Servlet的初始化阶段&#xff0c;会调用init()方法进行初始化操作&#xff0c;在DispatcherSe…

刚刚!奥特曼终于透露了GPT-5的最新消息!

原 创作者 | Tscom、王二狗 大爆料&#xff01;OpenAI被实锤正在研发GPT-5&#xff01; 还是OpenAI的CEO Sam Altman 亲口证实的。 今日&#xff0c;奥特曼接受《金融时报》的采访&#xff0c;透露了很多OpenAI的下一步计划&#xff0c;二狗帮大家整理成以下10个要点&#x…

实现定时巡检接口,测试不通过时自动发邮件

背景是这样的&#xff1a;最近组织架构调整&#xff0c;我们这个团队部分人员调入到了另外的业务组&#xff0c;因此她之前负责的业务需要交接给我们。 其中一个是接口每日监测&#xff0c;之前这个同事的做法是每天去手动点下按钮来跑接口测试&#xff0c;然后看一眼接口测试…

这 11 个 for 循环优化你得会

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

容器化nacos部署并实现服务发现(gradle)

1.如何容器化部署mysql 2. 如何容器化部署nacos 为不暴露我的服务器地址&#xff0c;本文全部使用localhost来代替服务器地址&#xff0c;所有的localhost都应该调整为你自己的服务器地址。 为不暴露我的服务器地址&#xff0c;本文全部使用localhost来代替服务器地址&#x…

Vue中组件与插件:究竟有何不同?详细解析带你get到核心差异!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、组…

VPN专题:VPN的基本概述

一、概述 VPN即虚拟专用网&#xff0c;泛指通过VPN技术在公用网络上构建的虚拟专用网络。VPN用户在此虚拟网络中传输私网流量&#xff0c;在不改变网络现状的情况下实现安全、可靠的连接。 二、VPN的分类 根据建设单位不同 根据组网方式不同 根据实现的网络层次 三、VPN的实现…

数据结构第二课 -----线性表之单向链表

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

以太网和局域网

计算机网络的定义 计算机网络是一个将分散的、具有独立功能的计算机&#xff0c;通过通信设备与线路连接起来&#xff0c;由根据协议编写的软件来实现的资源共享和信息传递的系统 计算机网络的分类 广域网是互联网的核心部分 局域网 常见的局域网拓扑结构有4大类&#xff1a…

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

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

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

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

【汇编】计算机的组成

文章目录 前言一、计算机的基本组成1.1 中央处理器&#xff08;CPU&#xff09;1.2 内存指令和数据存储的位置计算机中的存储单元计算机中的总线地址总线数据总线控制总线 1.3 输入设备和输出设备1.4 存储设备 二、计算机工作原理三、计算机的层次结构总结 前言 计算机是现代社…

Leetcode 【1334. 阈值距离内邻居最少的城市】

有 n 个城市&#xff0c;按从 0 到 n-1 编号。给你一个边数组 edges&#xff0c;其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边&#xff0c;距离阈值是一个整数 distanceThreshold。 返回能通过某些路径到达其他城市数目最少、且路径距离…

【C++】——继承和派生

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

详细的完美转发

不要假装努力&#xff0c;结果不会陪你演戏。文章目录 完美转发的使用场景完美转发 完美转发的使用场景 请看下面的这个代码 #include<iostream> using namespace std; void func(int&& t) {cout<<"int&&"<<endl;return; } void…