LeetCode 热题 100_环形链表(25_141_简单_C++)(哈希表;快慢指针)

LeetCode 热题 100_环形链表(25_141)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(哈希表):
        • 思路二(快慢指针):
      • 代码实现
        • 代码实现(思路一(哈希表)):
        • 代码实现(思路二(快慢指针)):

题目描述:

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

输入输出样例:

示例 1:
请添加图片描述

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:
请添加图片描述

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:
请添加图片描述

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:
链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。

题解:

解题思路:

思路一(哈希表):

1、使用一个哈希集合来存储遍历到的结点的地址。如果遍历到的结点不存在哈希集合中,则将该节点添加到哈希集合中。如果遍历到的结点已经存在哈希集合中则存在环,如果遍历整个链表结束则无环。

2、解题步骤
① 创建哈希集合用于进行环的判断。
② 遍历链表中的结点,如果遍历到的结点不存在哈希集合中,则将该节点添加到哈希集合中。如果遍历到的结点已经存在哈希集合中则存在环。
③ 遍历整个链表结束则无环。

3、复杂度分析:
① 时间复杂度:O(N),其中 N 是链表中的节点数。最坏情况下我们需要遍历每个节点一次(环可能在中间部分)。
② 空间复杂度:O(N),其中 N 是链表中的节点数。主要为哈希表的开销,最坏情况下我们需要将每个节点插入到哈希表中一次。

思路二(快慢指针):

1、使用快慢指针,快指针每次移动2步,慢指针每次移动1步。如果没有环,fast会先到达末尾nullptr。如果存在环的话,快指针与慢指针会在环中每次缩进一个单位的距离,最终快指针会追上慢指针,达到fast=slow的条件。

2、解题步骤
① 首先判断链表是否为空,第一个结点的next是否为空。
② 将slow指向首节点,fast指向首节点的next结点(防止一开始slow=fast的情况,且注意一个结点也可成环)。
③ 遍历单链表,slow指针每次移动一步,fast指针每次移动两步。
④ 如果fast到达链表的末尾则无环,如果最后fast==slow则存在环。

3、复杂度分析
① 时间复杂度:O(N),其中 N 是链表中的节点数。
当链表中不存在环时,快指针将先于慢指针到达链表尾部,为O(N/2)。
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。当慢指针移动到进入环的结点时,此时快指针已经在环上,快慢指针的最大距离为环的长度减一,所以。所以为O(N)。

② 空间复杂度:O(1)。我们只使用了两个指针的额外空间。

代码实现

代码实现(思路一(哈希表)):
bool hasCycle1(ListNode *head) {//mp用于存放没遍历过的结点地址unordered_set<ListNode*> mp;//如果遍历到的结点不存在哈希集合中,则将该节点添加到哈希集合中。如果遍历到的结点已经存在哈希集合中则存在环。while(head!=nullptr) {if(mp.count(head)){return true;}mp.insert(head);head=head->next;}return false;
}
代码实现(思路二(快慢指针)):
bool hasCycle2(ListNode *head) {//先排除特殊情况方便快慢指针的赋值 if(head==nullptr||head->next==nullptr){return false;}//注意初始时fast是slow后的一个结点(避免一开始相同的情况) ListNode *fast=head->next,*slow=head;//当slow==fast时存在环,如果fast到达末尾则不存在环 while(slow!=fast){if(fast==nullptr||fast->next==nullptr){return false;}fast=fast->next->next;slow=slow->next; } return true;
}

以思路二为例完成代码调试

#include<iostream>
#include<vector>
using namespace std;struct ListNode{int val;ListNode *next;ListNode(int x):val(x),next(nullptr){}
};//尾插法创建单链表 
ListNode* createList(const vector<int> &a){ListNode *head=nullptr,*tail=nullptr;for(const auto &val:a){ListNode *newNode=new ListNode(val);if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}} return head;
}//将单链表改成环状链表(注意这里仅构造末尾存在环的情况)
ListNode* createCircularList(ListNode *head,int pos){if(pos==-1){return head;} ListNode *posNode=head;//找到环形的入口结点 while(pos){posNode=posNode->next;--pos;}//从入口结点到尾结点 ListNode *tail=posNode;while(tail->next!=nullptr){tail=tail->next;}//将尾节点的next指针指向入口节点形成环 tail->next=posNode;return head;
} //判断是否构成环形链表
bool hasCycle2(ListNode *head) {//先排除特殊情况方便快慢指针的赋值 if(head==nullptr||head->next==nullptr){return false;}//注意初始时fast是slow后的一个结点(避免一开始相同的情况) ListNode *fast=head->next,*slow=head;//当slow==fast时存在环,如果fast到达末尾则不存在环 while(slow!=fast){if(fast==nullptr||fast->next==nullptr){return false;}fast=fast->next->next;slow=slow->next; } return true;
}int main(){vector<int> a={1,2};int pos=0;//创建单链表 ListNode *head=createList(a);//将单链表形成环 ListNode *cir_head=createCircularList(head,pos);//判断是否存在环 if(hasCycle2(cir_head)){cout<<"It's a circular linked list";}else{cout<<"It's not a circular linked list";}return 0;
} 

LeetCode 热题 100_环形链表(25_141)原题链接

unordered_map和unordered_set对比及用法请点击此链接

ListNode(int x):val(x),next(nullptr){}解读请点击此链接

欢迎大家和我沟通交流(✿◠‿◠)

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

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

相关文章

GTC2024 回顾 | 优阅达携手 HubSpot 亮相上海,赋能企业数字营销与全球业务增长

从初创企业入门到成长型企业拓展&#xff0c;再到 AI 驱动智能化运营&#xff0c;HubSpot 为企业的每步成长提供了全方位支持。 2024 年 11 月下旬&#xff0c;备受瞩目的 GTC2024 全球流量大会&#xff08;上海&#xff09;成功举办。本次大会汇聚了全国内多家跨境出海领域企业…

在VSCode 的终端或虚拟环境中运行git --version 无法识别,但是在电脑上已经装了git

刚刚在我的电脑上安装了 Git&#xff0c;装完最后有个报错弹窗&#xff0c;之后在 VSCode 的终端或虚拟环境中无法识别 git&#xff0c;上网查阅了资料&#xff0c;发现通常是由于以下原因引起的: 一. Git 未添加到系统的 PATH 环境变量 问题描述 安装 Git 后&#xff0c;系…

Text2SQL(NL2sql)对话数据库:设计、实现细节与挑战

Text2SQL&#xff08;NL2sql&#xff09;对话数据库&#xff1a;设计、实现细节与挑战 前言1.何为Text2SQL&#xff08;NL2sql&#xff09;2.Text2SQL结构与挑战3.金融领域实际业务场景4.注意事项5.总结 前言 随着信息技术的迅猛发展&#xff0c;人机交互的方式也在不断演进。…

Tongweb7049M4有关SSL/TLS 服务器瞬时 Diffie-Hellman 公共密钥过弱的处理方案(by lqw)

前提条件&#xff1a;Tongweb7049M4已在http通道里配置了https&#xff08;如何配置https可以参考这个帖子&#xff1a;东方通TongWEB添加Https证书&#xff0c;开启SSL&#xff09; 遇到客户在配置了https后&#xff0c;扫描漏洞提示&#xff1a; 有关SSL/TLS 服务器瞬时 Dif…

Jenkins部署svn项目

下载 Jenkins 的安装和设置 加载插件太慢&#xff0c;更换镜像地址 http://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 安装svn插件 安装Deploy to container Plugin 工具配置jdk和maven 后端部署 源码管理添加svn地址和认证 增加构建步骤 Invoke to…

嵌入式入门Day27

IO day3 文件IO文件描述符分配过程 相关函数 作业 文件IO 文件IO&#xff1a;基于系统调用的API函数接口特点&#xff1a;每一次调用文件IO&#xff0c;系统都会从用户态到内核态之间切换&#xff0c;效率很低作用&#xff1a;后期学习进程间通信&#xff0c;管道&#xff0c;…

复现论文:PromptTA: Prompt-driven Text Adapter for Source-freeDomain Generalization

github&#xff1a;zhanghr2001/PromptTA: Source-free Domain Generalization 论文&#xff1a;[2409.14163] PromptTA: Prompt-driven Text Adapter for Source-free Domain Generalization 自己标注&#xff1a;PromptTA: Prompt-driven Text Adapter for Source-free Domai…

在Windows上安装NVM(Node Version Manager)

NVM&#xff08;Node Version Manager&#xff09;是一个非常实用的工具&#xff0c;可以帮助开发者在同一台机器上管理多个Node.js版本。本文将介绍如何在Windows上安装NVM&#xff0c;并提供一些常用命令的说明。 一、下载和安装NVM 下载NVM安装程序 访问NVM for Windows的发…

记录 idea 启动 tomcat 控制台输出乱码问题解决

文章目录 问题现象解决排查过程1. **检查 idea 编码设置**2. **检查 tomcat 配置**3.检查 idea 配置文件4.在 Help 菜单栏中&#xff0c;修改Custom VM Options完成后保存&#xff0c;并重启 idea 问题现象 运行 tomcat 后&#xff0c;控制台输出乱码 解决排查过程 1. 检查 id…

《HTML 的变革之路:从过去到未来》

一、HTML 的发展历程 图片: HTML 从诞生至今&#xff0c;经历了多个版本的迭代。 &#xff08;一&#xff09;早期版本 HTML 3.2 在 1997 年 1 月 14 日成为 W3C 推荐标准&#xff0c;提供了表格、文字绕排和复杂数学元素显示等新特性&#xff0c;但因实现复杂且缺乏浏览器…

鸿蒙手机文件目录

最近在开发鸿蒙&#xff0c;想把文件从电脑上发送到鸿蒙上我的手机APP的根目录&#xff0c;但是试了几次目录都不对&#xff0c;最后终于找到了&#xff0c;在这里记录一下 鸿蒙手机路径: /storage/media/100/local/files/Docs 将文件从电脑发送到手机&#xff1a;hdc file s…

SQL注入--堆叠注入

一.基本概念 堆叠注入概念&#xff1a;在 SQL 中&#xff0c; 分号&#xff08;;&#xff09; 是用来表示一条 sql 语句的结束。 试想一下我们在 ; 结束一个 sql语句后继续构造下一条语句&#xff0c; 会不会一起执行&#xff1f; 因此这个想法也就造就了堆叠注入。 二.堆叠注入…

lspci简介

lspci命令用于列出系统中所有pci设备信息,其输出信息包括设备的bdf地址(总线号、设备号和功能号)、设备类型、厂商信息等。 lspci命令的基本用法: lspci:列出所有pci设备的详细信息 参数: -v:显示详细信息,包括驱动程序、总线和端口等信息 -t:以属性结构显…

【论文阅读】PRIS: Practical robust invertible network for image steganography

内容简介 论文标题&#xff1a;PRIS: Practical robust invertible network for image steganography 作者&#xff1a;Hang Yang, Yitian Xu∗, Xuhua Liu∗, Xiaodong Ma∗ 发表时间&#xff1a;2024年4月11日 Engineering Applications of Artificial Intelligence 关键…

Linux DNS域名解析服务器

DNS简介 DNS &#xff08; Domain Name System &#xff09;是互联网上的一项服务&#xff0c;它作为将域名和 IP 地址相互映射的一个分 布式数据库&#xff0c;能够使人更方便的访问互联网。 DNS 使用的是 53 端口&#xff0c; 通常 DNS 是以 UDP 这个较快速的数据传输协议…

Vercel部署前端部署

Vercel 部署 今天要讲的是如何对别人向自己的开源仓库提的PR进行自动代码审核 1. 注册并登录Vercel 访问 Vercel官网点击右上角的"Sign Up"选择使用GitHub、GitLab、Bitbucket或邮箱注册完成注册流程并登录 2. 连接代码仓库 在Vercel仪表板,点击"New Proje…

LeetCode面试题04 检查平衡性

题目&#xff1a; 实现一个函数&#xff0c;检查二叉树是否平衡。在这个问题中&#xff0c;平衡树的定义如下&#xff1a;任意一个节点&#xff0c;其两棵子树的高度差不超过 1。 一、平衡树定义&#xff1a; 二叉树&#xff0c;一种由节点组成的树形数据结构&#xff0c;每…

【一文了解】C#基础-接口

目录 1. 定义 2. 接口的特点与规则 3. 接口的实现 3.1单接口实现 3.2多接口实现 4. 接口的作用和用途 1)扩展行为 2)规范行为 3)降低耦合 5. 接口与继承的比较 1)继承 2)接口 6. 接口与抽象类的比较 1)IComparable(比较器&#xff0c;常用) 2)IComparer(比较器)…

Notable是一款优秀开源免费的Markdown编辑器

一、Notable简介 ‌ Notable‌是一款开源的跨平台Markdown编辑器&#xff0c;支持Linux、MacOS、Windows以及国产操作系统等多种主流操作系统。它以其高颜值和强大的功能&#xff0c;成为了许多用户的首选工具。 主要特性 实时预览‌&#xff1a; Notable提供了实时预览功能&…

方案解读:46页数字化企业制造运营管理(MOM)系统运营实践方案

本文概述了数字化企业制造运营管理(MOM)系统的核心要素与实践路径,深入探讨了数字化企业建设的丰富内涵。数字化企业以智能制造为核心,融合了智能终端、智能制造单元、工业4.0边缘技术、赛博物理系统(CPS)等前沿技术,构建了数字化车间、智能工厂等高效生产环境。通过工业…