【算法与数据结构】142、LeetCode环形链表 II

news2025/2/12 1:01:36

文章目录

  • 一、题目
  • 二、哈希法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述
在这里插入图片描述

二、哈希法

  思路分析:这道题也可以用双指针法去解,这里我介绍一种哈希法。利用set集合的值不可重复的特性首先我们定义一个集合链表指针s1,然后将链表中的每个指针依次放入集合当中,存在循环时就会第二次经过循环的首节点,终止循环然后记录这个节点即可程序当中insert返回参数是一个对组,对组的第二个元素是bool类型,用来判断是否插入成功
  程序如下

class Solution {
public:
	ListNode* detectCycle(ListNode* head) {
		//思路:用哈希表记录走过的结点,当第二次走过某个结点,则为第一个入环的结点
		set<ListNode*> s1;
		ListNode* p = head;
		s1.insert(p);
		while (p != NULL)
		{
			p = p->next;
            if (!s1.insert(p).second) {
                return p;
            }
		}
        return NULL;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),最坏情况需要遍历链表。
  • 空间复杂度: O ( n ) O(n) O(n),最坏情况需要链表长度的空间。

三、完整代码

  代码当中构建了一个链表类,写了一个利用数组生成链表ChainGenerator函数(不带循环,不带循环首节点)、链表打印LinkListPrint函数。循环链表CyCleChainGenerator函数参数为循环首节点和首节点位置。找到首节点位置然后插入,再让原来的链表尾节点指向这个循环首节点,循环就生成了

# include <iostream>
# include <set>
using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode() : val(0), next(nullptr) {}
	ListNode(int x) : val(x), next(nullptr) {}
	ListNode(int x, ListNode* next) : val(x), next(next) {}
};

// 链表类
class MyLinkedList {
public:
    // 构造函数
    MyLinkedList() {
        _FakeNode = new ListNode(0, NULL);    // 虚假头结点
        _size = 0;
    }
    // 成员函数
    void ChainGenerator(int arr[], int len);
    void LinkListPrint(string str); 
    void CyCleChainGenerator(ListNode* CycleFirstNode, int CycleFirstNodeIndex);
    // 成员变量
    int _size;
    ListNode* _FakeNode;
};

void MyLinkedList::ChainGenerator(int arr[], int len) {
    if (_FakeNode->next != NULL) return;
    ListNode* head = new ListNode(arr[0], NULL);
    ListNode* p = head;
    for (int i = 1; i < len; i++) {
        ListNode* pNewNode = new ListNode(arr[i], NULL);
        p->next = pNewNode; // 上一个节点指向这个新建立的节点
        p = pNewNode; // p节点指向这个新的节点
    }
    _FakeNode->next = head;
    _size = len;
}

void MyLinkedList::LinkListPrint(string str) {
    cout << str << endl;
    ListNode* cur = _FakeNode;
    int index = _size;
    while (index-- >0) {
        cout << cur->next->val << ' ';
        cur = cur->next;
    }
    cout << endl;
}

void MyLinkedList::CyCleChainGenerator(ListNode* CycleFirstNode, int CycleFirstNodeIndex) {
    if (CycleFirstNodeIndex > _size) return;
    if (CycleFirstNodeIndex < 0) CycleFirstNodeIndex = 0;
    ListNode* cur = _FakeNode; // 虚结点 
    // 添加循环的第一个节点
    // 需要断开上一一个阶段的链接,从插入位置的上一个索引开始处理
    while (CycleFirstNodeIndex--) {
        cur = cur->next;
    }
    CycleFirstNode->next = cur->next;
    cur->next = CycleFirstNode;
    // 找到尾节点,指向循环第一个节点
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = CycleFirstNode;
    _size++;
}

class Solution {
public:
	ListNode* detectCycle(ListNode* head) {
		//思路:用哈希表记录走过的结点,当第二次走过某个结点,则为第一个入环的结点
		set<ListNode*> s1;
		ListNode* p = head;
		s1.insert(p);
		while (p != NULL)
		{
			p = p->next;
            if (!s1.insert(p).second) {
                return p;
            }
		}
        return NULL;
	}
};

int main()
{
	int arr[] = { 2 };
	int arr_len = sizeof(arr) / sizeof(int);
    MyLinkedList m1;
    m1.ChainGenerator(arr, arr_len);
    ListNode* CycleFirstNode = new ListNode(1, NULL);
    m1.CyCleChainGenerator(CycleFirstNode, 0);
    m1.LinkListPrint("目标循环链表:");
	Solution s1;
    ListNode* result = s1.detectCycle(m1._FakeNode->next);
    if (result != NULL) {
        cout << "循环第一个节点:" << endl;
        cout << "result->val: " << result->val << endl;
    }
    else {
        cout << "NULL" << endl;
    }    
	system("pause");
	return 0;
}

end

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

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

相关文章

什么触控笔好用又便宜?性价比高的苹果笔推荐

而对于一些将IPAD作为学习工具的人来说&#xff0c;这款苹果Pencil无疑是必不可少的。不过&#xff0c;苹果版Pencil的价格实在是太高了&#xff0c;很多人都买不起。所以&#xff0c;最好的办法就是使用平替的电容笔。我是在前几年就开始使用ipad了&#xff0c;同时也是一位数…

快速入门教程:神经常微分方程 (Neural ODE)

神经常微分方程(Neural Ordinary Differential Equations,简称 Neural ODE)是一种基于常微分方程(Ordinary Differential Equations,ODEs)的深度学习方法,它结合了传统的ODE数值求解技术和神经网络模型。通过使用ODE来建模数据的演化过程,Neural ODE可以自动地学习数据…

项目管理专业人员能力评价(CSPM)对比PMP哪个好考?

2021年10月&#xff0c;中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系&#xff0c;开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会&#xff08;CAS&#xff09;组织开展的项…

编译opencv环境搭建:vs2019 + cmake-3.25 + opencv-4.5.5

一 下载vs2019 链接&#xff1a;Downloads - Visual Studio Subscriptions Portal 下载社区版本&#xff0c;因为是免费的&#xff0c;大家随便用 下载成功后直接安装就可以了。 有的环境安装好后在属性管理器中可能没有 Microsoft.Cpp.x64 文件 从如下链接下载 Microsoft.C…

三、OkHttp_缓存

一、OKHttp的缓存逻辑 OKHttp 把重复请求的数据缓存在本地&#xff0c;并设置超时时间&#xff0c;在规定时间内&#xff0c;客户端不再向远程请求数据&#xff0c;而是直接从本地缓存中取数据。 一来提高了响应速度&#xff0c;二来节省了网络带宽&#xff08;也就是节省了钱…

如何使用uni-app开发微信小程序

web前端-基于uniapp的微信小程序项目 起步uni-app简介开发工具下载 HBuilderX安装 HBuilderX安装 scss/sass 编译快捷键方案切换修改编辑器的基本设置新建uni-app项目把项目运行到微信开发者工具 scss语法学习安装相关插件和配置基础格式选择器的嵌套父选择器后面添加内容 &…

麒麟系统在线安装docker(x86/arm)

文章目录 一、查看系统版本&#xff0c;确认版本二、查看系统架构三、下载安装docker-ceX86架构安装aarch64架构 一、查看系统版本&#xff0c;确认版本 [rootlocalhost ~]# cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Sword)二、查看系统架构 [root…

Windows内存诊断工具卡住无响应怎么办?

Windows内存诊断工具是一个有用的程序&#xff0c;用于检查您的RAM是否存在潜在问题。当系统性能降低、频繁冻结或者蓝屏时&#xff0c;用户可以通过内存诊断工具检查和修复内存方面的问题。该工具具有三种测试模式&#xff0c;基本、标准和扩展模式&#xff0c;其中扩展模式下…

在UOS上安装及更新恒辉桌面软件

UOS作为一颗冉冉升起的新星&#xff0c;吸引了众多国内用户及厂商的目光。 而新的系统势必面临着一个问题——软件及应用的适配性。各个软件厂商需要单独为此适配产品。 2022年2月&#xff0c;支持全四路国产CPU&#xff08;x86架构、arm架构、龙芯、申威&#xff09;的数据库…

chatgpt赋能python:Python如何打印结果

Python如何打印结果 Python是一种高级编程语言, 它也是一种解释型语言&#xff0c;也就是说&#xff0c;程序员不必把Python代码编译成机器码或者字节码。它利用缩进来表示块结构&#xff0c;同时使用一些特殊的关键字来定义变量和类等。 在Python中&#xff0c;有多种方式来…

算法课设 戳气球问题实验报告 动态规划

戳气球实验报告 目录 一、题目 二、分析原问题并做调整 三、分析子问题及其递推关系 四、确定dp数组的计算顺序 五、复杂度分析 六、具体实现代码 七、填表示例寻找最优解和最优方案 八、总结 九、致谢 一、题目 有n个气球&#xff0c;编号为0到n-1&#xff0c;每个…

管理类联考——逻辑——知识篇——第三章 三段论(考2题)(以性质命题为基础,最常用推理)

第三章 三段论&#xff08;考2题&#xff09;&#xff08;以性质命题为基础&#xff0c;最常用推理&#xff09; 一、三段论的基本结构 基本结构1&#xff08;最简单&#xff0c;不考&#xff09;&#xff1a; 所有A是B 所有B是C 得&#xff1a;所有A是C 基本结构2&#xff…

网络安全系统教程+学习路线(自学笔记)

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

MySQL查询优化大揭秘!看这些关键数据,让你的数据库速度飞起来!

大家好&#xff0c;我是小米&#xff0c;今天给大家分享一些关于MySQL查询优化的干货。在数据库开发和维护中&#xff0c;优化查询是至关重要的一环。通过合理的优化&#xff0c;我们可以让数据库的查询速度事半功倍。那么&#xff0c;在MySQL的查询计划中&#xff0c;有哪些关…

Spring五大类注解和方法注解

1.配置(重要)2.添加五大类注解2.1 Controller&#xff08;控制器存储&#xff09;2.2 Service&#xff08;服务存储&#xff09;2.3 repository&#xff08;仓库存储&#xff09;2.4 Component&#xff08;组件存储&#xff09;2.5 Configuration&#xff08;配置存储&#xff…

【Python】基础内容

简介 面向对象&#xff0c;解释型的编程语言使用缩进作为逻辑层次 运行效率较低 单行注释&#xff1a;以#开头&#xff1a;#注释内容多行注释&#xff1a;以一对三个双引号引起来的内容&#xff1a; “”“注释内容”“” 数据类型 type(被查看类型的数据)&#xff1a;查看…

KETTLE Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found

kettle链接mysql&#xff1a;抛出异常 Driver class org.gjt.mm.mysql.Driver could not be found 这是因为你没有下载对应的mysql驱动程序包&#xff08;DRIVER.jar&#xff09;到你的kettle下&#xff1a; 1 查看你的mysql版本 C:\Users\22077>mysql --version mysql …

快速拼接字符串的新类StringJoiner~

初识StringJoiner类&#xff1a; StringJoiner 是 Java 8 新增的一个类&#xff0c;它不仅提供了一种快速、方便地将多个字符串拼接成一个字符串的方法&#xff0c;并且在拼接之时还可以指定分隔符、前缀和后缀&#xff0c;以及添加多个字符串&#xff0c;最终输出拼接后的字符…

9-基于stm32的MAX31865铂电阻PT100测温全套资料(原理图+教程+程序)

编号: 009 本项目可以通过PT100测温&#xff0c;测温范围为: -200~420C&#xff0c;采用1.8寸OLED显示该资料已经过实物验证&#xff0c;实物中是通过触发GPIO来测量当前的温度&#xff0c;程序注释非常详细&#xff0c;容易上手 经过实验验证&#xff0c;切实可行!配备详细代码…

p5.js 到底怎么设置背景图?

theme: smartblue 本文简介 点赞 关注 收藏 学会了 在 《p5.js 光速入门》 里我们学过加载图片元素&#xff0c;学过过背景色的用法&#xff0c;但当时没提到背景图要怎么使用。 本文就把背景图这部分内容补充完整&#xff0c;并且会提到在 p5.js 里使用背景图的一些注意点。…