哈希表题目:环形链表 II

news2024/11/24 6:46:18

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
      • 进阶
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 证明
    • 代码
    • 复杂度分析

题目

标题和出处

标题:环形链表 II

出处:142. 环形链表 II

难度

2 级

题目描述

要求

给你一个链表的头结点 head \texttt{head} head,返回链表开始入环的结点。如果链表无环,则返回 null \texttt{null} null

如果链表中有某个结点,可以通过连续跟踪 next \texttt{next} next 指针再次到达,则链表中存在环。评测系统内部使用 pos \texttt{pos} pos 表示链表尾结点的 next \texttt{next} next 指针连接到的结点下标(下标从 0 \texttt{0} 0 开始)。如果 pos \texttt{pos} pos -1 \texttt{-1} -1,则在该链表中没有环。注意 pos \texttt{pos} pos 不作为参数进行传递。

不允许修改链表。

示例

示例 1:

示例 1

输入: head   =   [3,2,0,-4],   pos   =   1 \texttt{head = [3,2,0,-4], pos = 1} head = [3,2,0,-4], pos = 1
输出:索引为 1 \texttt{1} 1 的链表结点
解释:链表中有一个环,其尾部连接到第 1 \texttt{1} 1 个结点。

示例 2:

示例 2

输入: head   =   [1,2],   pos   =   0 \texttt{head = [1,2], pos = 0} head = [1,2], pos = 0
输出:索引为 0 \texttt{0} 0 的链表结点
解释:链表中有一个环,其尾部连接到第 0 \texttt{0} 0 个结点。

示例 3:

示例 3

输入: head   =   [1],   pos   =   -1 \texttt{head = [1], pos = -1} head = [1], pos = -1
输出: no   cycle \texttt{no cycle} no cycle
解释:链表中没有环。

数据范围

  • 链表中结点的数目范围是 [0,   10 4 ] \texttt{[0, 10}^\texttt{4}\texttt{]} [0, 104]
  • -10 5 ≤ Node.val ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{Node.val} \le \texttt{10}^\texttt{5} -105Node.val105
  • pos \texttt{pos} pos -1 \texttt{-1} -1 或者链表中的一个有效下标

进阶

你是否可以使用 O(1) \texttt{O(1)} O(1) 空间解决此问题?

解法一

思路和算法

如果链表中存在环,则链表的尾结点的 next \textit{next} next 指针指向链表中的一个结点,被指向的结点为链表开始入环的结点。从链表的头结点 head \textit{head} head 开始遍历链表,如果链表存在环,则在访问尾结点之后会重复访问链表开始入环的结点,链表开始入环的结点是第一个被重复访问的结点。

如果链表中没有环,则任何结点都不会被重复访问。

因此可以遍历链表,寻找第一个被重复访问的结点。为了判断是否有结点被重复访问,可以使用哈希集合存储访问过的结点。

在遍历链表的过程中将访问到的每个结点加入哈希集合,遇到的第一个已经在哈希集合中的结点即为链表开始入环的结点,返回该结点。如果遍历链表结束到达 null \text{null} null 时仍没有遇到已经在哈希集合中的结点,则链表中没有环,返回 null \text{null} null

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> visited = new HashSet<ListNode>();
        ListNode temp = head;
        while (temp != null) {
            if (!visited.add(temp)) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的结点数。链表中的每个结点最多遍历一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的结点数。需要使用哈希集合存储链表中的全部结点。

解法二

思路和算法

对于循环链表,另一个常用的方法是快慢指针。使用快慢指针寻找链表开始入环的结点分成两步。

第一步是使用快慢指针遍历链表并判断是否会相遇。

初始时,快指针和慢指针都位于链表的头结点。每次将快指针移动两步,慢指针移动一步,在至少移动一次的情况下,可能有两种情况:

  • 如果快慢指针相遇,则链表中存在环,将快慢指针相遇的结点称为相遇点,从链表的头结点和相遇点开始遍历链表寻找链表开始入环的结点;

  • 如果快指针到达链表末尾,则链表中不存在环,返回 null \text{null} null

第二步是将两个指针分别从链表的头结点和相遇点开始遍历链表寻找链表开始入环的结点。

初始时,两个指针分别位于链表的头结点和相遇点。每次将两个指针各移动一步,两个指针相遇的结点即为链表开始入环的结点。

证明

假设链表入环之前的部分有 x x x 个结点(即从链表的头结点开始移动 x x x 步到达链表开始入环的结点),从链表开始入环的结点开始移动 y y y 步到达相遇点,从相遇点开始移动 z z z 步到达链表开始入环的结点,即环的长度是 y + z y + z y+z,其中 x x x y y y z z z 都是非负整数且 y + z ≥ 1 y + z \ge 1 y+z1。如图所示。

图 1

当快慢指针相遇时,快慢指针都移动了 x + y x + y x+y 次,其中快指针移动了 2 ( x + y ) 2(x + y) 2(x+y) 步,慢指针移动了 x + y x + y x+y 步。假设此时快指针已经在环内移动了 k k k 整圈, k k k 是正整数,则有 2 ( x + y ) = x + k ( y + z ) + y 2(x + y) = x + k(y + z) + y 2(x+y)=x+k(y+z)+y,整理得 x = ( k − 1 ) ( y + z ) + z x = (k - 1)(y + z) + z x=(k1)(y+z)+z

由于 x x x 是链表入环之前的部分的结点数量,因此从链表的头结点开始移动 x x x 步到达链表开始入环的结点。

根据 x = ( k − 1 ) ( y + z ) + z x = (k - 1)(y + z) + z x=(k1)(y+z)+z 可知,从相遇点开始移动 x x x 步即为在环内移动 k − 1 k - 1 k1 整圈然后移动 z z z 步。由于从相遇点开始在环内移动 k − 1 k - 1 k1 整圈之后回到相遇点,从相遇点开始移动 z z z 步到达链表开始入环的结点,因此从相遇点开始移动 x x x 步到达链表开始入环的结点。

由于从链表的头结点开始移动 x x x 步和从相遇点开始移动 x x x 步都到达链表开始入环的结点,因此上述做法中,位于链表的头结点和相遇点的两个指针同时移动 x x x 步之后同时到达链表开始入环的结点。

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        ListNode meet = null;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                meet = fast;
                break;
            }
        }
        if (meet == null) {
            return null;
        }
        ListNode pointer1 = head, pointer2 = meet;
        while (pointer1 != pointer2) {
            pointer1 = pointer1.next;
            pointer2 = pointer2.next;
        }
        return pointer1;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的结点数。第一次遍历到快慢指针相遇的移动次数不超过链表的结点数,第二次遍历到找到链表开始入环的结点的移动次数也不超过链表的结点数。

  • 空间复杂度: O ( 1 ) O(1) O(1)

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

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

相关文章

CSDN周赛第16期-100分满分题解

前言 这是时隔两年再参加比赛了&#xff0c;上次参加算法竞赛还是2020年在公司1024活动的时候。当时获得了二等奖&#xff08;switch套装&#xff09;和一个快题奖&#xff08;小米行李箱&#xff09;。 这次比赛获得了满分&#xff0c;也还不错。题目除了二维积水的问题&…

8Manage:提高项目执行力的策略有哪些?

在项目管理中实施执行战略&#xff0c;将战略目标转化为商业价值的企业将发现取得成功所涉及的大团队——最高管理层、中层管理人员、项目经理和项目团队。 以下是阻碍项目成功执行的六个主要差距&#xff1a; ● 缺少共同的理解 ● 缺乏参与的执行赞助者 ● 与战略目标不一致…

计算机网络—Nginx概述

文章目录nginx负载均衡&#xff1a;例&#xff1a;安装配置nginx————————————————————————————————nginx负载均衡&#xff1a; 请求会打到nginx上面&#xff0c;nginx可以用作负载均衡&#xff0c; 例&#xff1a;一个网站用一台服务器不够&a…

001 软件安装与配置

1、Anaconda安装及使用 1.1 下载地址 Anaconda3-2022.10-Windows-x86_64 1.2 Anaconda创建虚拟环境 下面均在Anaconda终端中输入 查看python版本 python --version1.2.1、Anaconda创建虚拟环境 conda create -n pytorch python3.9conda create 创建虚拟环境命令 -n pytor…

解决vue代码不规范而出现的问题:Eslint修复

当我们刚创建一个vue项目&#xff0c;写代码时候&#xff0c;因为代码写的不规范会出很多问题&#xff0c;报很多错误&#xff0c;除了一个一个去修改他们&#xff0c;还有没有其他办法去解决他们呢&#xff1f; 这里介绍三种办法去统一解决&#xff1a; 方法一&#xff1a;每…

MCU-51:让LED闪烁起来

目录一、LED闪烁1.1 编写代码1.2 延时函数1.3 由0和1控制实现二、LED流水灯2.1 流水灯基础版2.2 移位法实现LED流水灯一、LED闪烁 昨天我们初识单片机&#xff0c;点亮了一个灯开启了我们51单片机的学习之旅。那么今天我们来一步步深入学习。 1.1 编写代码 会了点亮一个灯&a…

嵌入式分享~IO相关1 ##

这里仅总结一下IO控制相关 单片机IO直接驱动继电器 上图是随便找到的两个不同型号的继电器。继电器就是个开关&#xff0c;这个开关是由它内部的线圈控制的&#xff0c;给线圈通电&#xff0c;继电器就吸合&#xff0c;开关就动作了。绝大部分的继电器反面都会有如下图一样的…

win10 git 标准化commit工具commitizen安装教程

1、 安装nodjs https://nodejs.org/en/ 下载最新版本 安装完成后&#xff0c;修改环境变量 默认 nodejs是有的&#xff0c;需要自己添加npm路径 2、安装commitizen 在桌面上右键打开power shell 查看node 和npm的版本&#xff0c;npm最好升级一下 升级命令问题 npm inst…

【HDR】曝光融合(Exposure Fusion)

文章目录0 前言1 算法细节1.1 Naive1.1.1 主要思想1.1.2 权重计算1.1.3 融合1.2 Multi-resolution2 实验3 参考0 前言 在曝光融合&#xff08;Exposure Fusion&#xff09;算法问世之前&#xff0c;多曝光序列合成用于显示的HDR需要两个步骤&#xff0c;第一步是将多张不同曝光…

MySql加密存储的数据,如何模糊搜索?

背景 蔚来被勒索 225 万美元&#xff0c;大量数据遭泄露&#xff01; 根据网络上流传的截图显示&#xff0c;黑客似乎掌握着蔚来内部员工数据 22800 条、车主用户身份证数据 399000 条、用户地址数据 6500000 条、注册用户数据 4850000 条、企业及企业代表联系人数据 10000 条…

dpdk编译

ubuntu网卡信息配置 虚拟机中除去最开始的一块网卡&#xff0c;再另外添加两块网卡&#xff0c;如下图所示 修改Ubuntu20_x64.vmx里面的配置信息 将ethernet0.virtualDev "e1000"里面的e1000更改成vmxnet3,因为e1000只支持网卡单队列&#xff0c;vmxnet3支持网卡对…

5G无线技术基础自学系列 | 5G移动性KPI

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 5G移动类KPI用来评估NR网络的移动性能&…

29. 如何通过 ABAP 代码给 SAP OData 元数据增添注解

笔者的这篇 SAP UI5 开发教程文章&#xff0c;* SAP UI5 应用开发教程之一百二十九 - 如何给 SAP UI5 SmartField 添加 Value Help 功能&#xff0c;有朋友留言&#xff1a; 你好&#xff0c;请教一个问题&#xff0c;请问如何在odata里面通过annotations添加一个自定义注解&am…

2022年哪些工具适合设计企业产品手册?

产品手册是什么&#xff1f; 产品手册是因特网发展的成果&#xff0c;是一种以移动端为基础进行在线营销的新内容&#xff0c;其中包含了对原有的纸质商品、小册子、促销软文、邀请函等现有促销资料进行数字化的更新。 产品手册是从传统的纸质公司样本书中升级而来的&#xf…

Git 入门

文章目录0. 前言学习目标参考教程链接1. Git概念1.1 什么是Git1.2 Git 的下载1.3 Git三大区域1.4 远程仓库2. Git的使用2.1 图形化操作2.1.1 IDEA图形化操作2.1.2 GitKraken(可选)2.2 命令行操作2.2.1 Git 配置2.2.2 分支命令2.2.3 拉取与推送3. 总结0. 前言 学习目标 了解 G…

面试官:你来说一下Spring IOC容器的创建过程

这篇文章主要讲解 IOC 容器的创建过程&#xff0c;让你对整体有一个全局的认识&#xff0c;文章没有复杂嵌套的 debug 流程&#xff0c;相对来说比较简单。 不 BB&#xff0c;上文章目录。 1. 基础知识 1.1 什么是 Spring IOC &#xff1f; IOC 不是一种技术&#xff0c;只是…

数据结构抽象数据类型的表示和实现

抽象数据类型(Abstract Data Type&#xff0c;ADT)是指一个数学模型以及定义在此数学模型上的一组操作。例如&#xff0c;“整数”是一个抽象数据类型&#xff0c;其数学特性和具体的计算机或语言无关。“抽象”的意义在于强调数据类型的数学特性。抽象数据类型和数据类型实质上…

Halcon常用算子(库函数)整理

目录一. 常规操作类1.1 tuple_length()1.2 tuple_find_first()1.3 tuple_gen_const()二. 机器视觉操作类2.1 read_image()2.2 get_image_size()2.3 intensity()2.4 zoom_image_factor()2.5 median_image()2.6 Gauss_filter()2.7 fft_generic()2.8 convol_fft()2.9 sub_image()2…

大白话给你讲明白数据仓库

数据仓库的本质就是完成从面向业务过程数据的组织管理到面向业务分析数据的组织和管理的转变过程。 数据仓库类比粮食仓库 业务过程数据的组织管理实际上就是由各种业务系统来完成的&#xff0c;比如ERP、CRM、OA等各类业务系统&#xff0c;解决的是基本的业务流程管理。通过…

PS的安装、背景、背景练习、雪碧图、线性渐变、径向渐变、电影卡片练习——06fontbackground

目录 一、PS的安装 二、背景(background-color、background-image、 background-repeat、background-position、background-clip、background-origin、background-size、background-attachment) 三、背景练习(背景重复—导航条的背景颜色是渐变的) 四、背景练习&#xff08…