【代码随想录 | Leetcode | 第七天】链表 | 链表相交 | 环形链表 II

news2024/12/24 9:06:26

前言

欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来链表相交和环形链表 II的分享

目录

  • 前言
  • 面试题 02.07. 链表相交
  • 142. 环形链表 II
  • 总结


面试题 02.07. 链表相交

✨题目链接点这里

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交:

在这里插入图片描述

题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

提示:

listA 中节点数目为 m
listB 中节点数目为 n

0 <= m, n <= 3 * 104
1 <= Node.val <= 105
0 <= skipA <= m
0 <= skipB <= n
如果 listA listB 没有交点,intersectVal 为 0
如果 listAlistB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]
思路:这道题目也是双指针的一种用法,我们先定义两个指针分别指向两个链表的头结点,然后让指向较长链表的指针朝后移动,和较短链表的那个指针对其,最后就是移动,循环比较,返回第一个 两个指针指向同一节点的情况,没找到则返回空

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA, *curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != nullptr) {
            lenA++;
            curA = curA->next;
        }
        while (curB != nullptr) {
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        if (lenA < lenB){
            swap(lenA,lenB);
            swap(curA,curB);
        }
        int gap = lenA - lenB;
        while (gap--) curA = curA->next;
        while (curA != nullptr) {
            if(curA == curB) return curA;
            curA = curA->next;
            curB = curB->next;
        }
        return nullptr;
    }
};

在这里插入图片描述

142. 环形链表 II

✨题目链接点这里
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。

示例 1:
在这里插入图片描述

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

示例 2:
在这里插入图片描述

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

示例 3:
在这里插入图片描述

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

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

思路:解决这个问题我们需要明确下面两个问题

  • 判断链表是否有环
  • 如果有环,如何找到这个环的入口

问题一:判断链表是否有环

可以使用快慢指针法,定义一个快指针 fast 和一个慢指针 slow ,从头结点开始,每次让快指针移动两个节点,慢指针每次移动一个节点,如果在途中相遇,则代表有环

相遇一定在环内相遇,这是为什么?快指针一定比慢指针先入环
为什么快慢指针一定会相遇?快指针一次移动两步,而慢指针一次移动一步,所以快指针相当于是以每次一步来追赶慢指针,所以一定会相遇

在这里插入图片描述

问题二:找环的入口

假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。
那么相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A
则有:(x + y) * 2 = x + y + n (y + z)
化简得x = (n - 1)(y + z) + z ,注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。当n等于一和大于一的效果是一样的,因为当n大于一就相当于快指针在环内多转了几圈

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != nullptr && fast->next != nullptr) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
                ListNode* index1 = head;
                ListNode* index2 = fast;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
        }
        return nullptr;
    }
};

在这里插入图片描述

总结

今天的收获还是挺大的,这个环形链表不难,但是很有意思,有点写数学题的感觉,一步一步揭开面纱真的很舒服~

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

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

相关文章

C/C++ new A与new A()的区别

在C中&#xff0c;POD是“Plain Old Data”的缩写&#xff0c;即“普通旧数据”。POD data是指一种特殊类型的数据结构&#xff0c;它们具有简单的内存布局&#xff0c;没有构造函数、虚函数、私有/保护非静态数据成员&#xff0c;也没有虚继承等特性。这些数据结构可以直接通过…

k8s与集群管理

从docker讲起 终于有人把 Docker 讲清楚了&#xff0c;万字详解&#xff01; Docker资源&#xff08;CPU/内存/磁盘IO/GPU&#xff09;限制与分配指南 默认情况下&#xff0c;Docker容器是没有资源限制的&#xff0c;它会尽可能地使用宿主机能够分配给它的资源。如果不对容器资…

C++--day3(内联函数、结构体、类、封装、this、构造函数、析构函数)

#include <iostream>using namespace std;class My_stack { private:int *ptr; //指向堆区空间int top; //记录栈顶元素int size; public://有参构造My_stack(int size):ptr(new int[size]),top(-1){this->sizesize;cout<<"My_stack::有参构造&…

基于STM32的智能喂养系统

基于STM32的智能喂养系统 系统简介 自动检测环境温湿度&#xff0c;当温湿度低于阈值时自动打开加湿器&#xff1b;自动检测水位&#xff0c;当水位低于阈值时自动加水&#xff1b;自动检测有害气体&#xff0c;当检测到有害气体时自动打开风扇&#xff1b;同步状态到微信小程…

中间件上云部署 zookeeper

中间件上云部署 zookeeper 企业级中间件上云部署 zookeeper一、环境说明二、zookeeper部署YAML资源清单准备三、zookeeper部署及部署验证四、zookeeper应用验证 企业级中间件上云部署 zookeeper 一、环境说明 storageclassingress 二、zookeeper部署YAML资源清单准备 # vim…

图解java.util.concurrent并发包源码系列,原子类、CAS、AtomicLong、AtomicStampedReference一套带走

图解java.util.concurrent并发包源码系列&#xff0c;原子类、CAS、AtomicLong、AtomicStampedReference一套带走 原子类为什么要使用原子类CAS AtomicLong源码解析AtomicLong的问题ABA问题AtomicStampedReference 高并发情况下大量的CAS失败&#xff0c;导致CPU空转 往期文章&…

百度智能汽车负责人储瑞松离职,智驾重心转向ANP3

作者 | 王博 HiEV从多个信息源获悉&#xff0c;百度集团副总裁、百度智能汽车事业部总经理储瑞松将从百度离职。一位知情人士透露&#xff0c;储瑞松「即将启程&#xff0c;返回美国」。 继百度Apollo技术骨干郭阳离职后&#xff0c;储瑞松的变动&#xff0c;更加直白地反映出百…

电动汽车高压测试方案

针对电动汽车道路试验的要求&#xff0c;风丘科技携手德国IPETRONIK共同推出了电动汽车高压测试方案。电动汽车测试通常有两种测量手段&#xff1a;第一种是测量模拟量信号&#xff0c;包括电压、电流、温度和高压&#xff1b;第二种是使用数据记录仪或CAN卡从车辆总线读取数据…

你一定要收好这个系统性能测试用例模板

引言 文档目的 [简述本文档的目的] 适用范围 [指明本文档的适用范围和读者对象。如本测试计划是在策略和方法的高度说明如何计划、组织和管理测试项目。测试计划应包含足够的信息&#xff0c;使测试人员明白项目需要做什么、是如何运作的。另外&#xff0c;测试计划只是测试的…

刚体运动学-速度和加速度的表示方法(连体坐标系和世界坐标系)

0. 符号定义 自己画了一个图 下标 b b b是连体坐标系原点 O b O_b Ob​相对世界坐标系原点 O p O_p Op​的矢量在世界坐标系下的表示。下标 p p p是观察点相对世界坐标系原点 O p O_p Op​的矢量在世界坐标系下的表示。下标 p / b p/b p/b是观察点相对连体坐标系原点 O b O_b…

Python实现将pdf,docx,xls,doc,wps,zip,xlsx,ofd链接下载并将文件保存到本地

前言 本文是该专栏的第31篇,后面会持续分享python的各种干货知识,值得关注。 在工作上,尤其是在处理爬虫项目中,会遇到这样的需求。访问某个网页或者在采集某个页面的时候,正文部分含有docx,或pdf,或xls,或doc,或wps,或ofd,或xlsx,或zip等链接。需要你使用python自…

Yalmip入门教程(2)-变量定义和操作

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译&#xff1a;https://yalmip.github.io/tutorials/ 1.决策变量的定义 1.1 sdpvar 上文简单介绍了sdpvar函数的用法&#xff0c;接下来将对其进行详细介绍。复习一下&#xff0c;sdpvar函数的基本语…

window10安装telnet

1、打开控制面板 2、点击程序和功能 3、点击启用或关闭Windows功能 4、选中Telnet客户端&#xff0c;然后点击确定&#xff0c;然后就可以使用telnent 主机 端口来查看本地是否能连通该主机的该端口。

Linux系统部署Tomcat详细教程(图文讲解)

前言&#xff1a;本篇博客教大家如何一步一步使用Linux系统去部署自己的Tomcat服务器&#xff0c;每一行代码都是我自己严格执行过的&#xff0c;共分为了8点进行阐述&#xff0c;逻辑清晰&#xff01; 目录 一、安装JDK环境 二、准备Tomcat安装包 三、安装Tomcat 四、配置…

【前端】求职必备知识点1-HTML

文章目录 DOCUTYPE的作用HTML语义化HTML5新特性iframedefer 和 async 标题链接【前端】求职必备知识点1-HTMLhttps://blog.csdn.net/karshey/article/details/131795380 DOCUTYPE的作用 DOCTYPE是document type (文档类型) 的缩写。 是HTML5中一种标准通用标记语言的文档类型…

《TCP IP网络编程》第七章

第七章&#xff1a;优雅的断开套接字的连接 TCP 的断开连接过程比建立连接更重要&#xff0c;因为连接过程中一般不会出现大问题&#xff0c;但是断开过程可能发生预想不到的情况。因此应该准确掌控。所以要掌握半关闭&#xff08;Half-close&#xff09;&#xff0c;才能明确断…

131、仿真-基于51单片机智能电子称HX711报警仿真设计(程序+原理图+PCB图+Proteus仿真+参考论文+元器件清单等)

摘 要 电子秤是将检测与转换技术、计算机技术、信息处理、数字技术等技术综合一体的现代新型称重仪器。它与我们日常生活紧密结合息息相关。 电子称主要以单片机作为中心控制单元&#xff0c;通过称重传感器进行模数转换单元&#xff0c;在配以键盘、显示电路及强大软件来组成…

【手撕C语言基础】递归

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

数据结构(王道)——数据结构之 二叉树

一、数据结构之 二叉树概念&#xff1a; 特殊的二叉树结构&#xff1a; 满二叉树完全二叉树 二叉排序树 平衡二叉树 二叉树基本概念总结&#xff1a; 二、二叉树的常用性质&#xff1a; 1、叶子结点比二分支结点多一个

汽车的空气悬架的功能以及发展趋势

空气悬架能实现什么功能以及发展趋势 了解空气悬架之前,首先得快速了解什么是悬架。 教科书说法是: 悬架系统是汽车的车架与车桥或车轮之间的一切传力连接装置的总称。悬架系统基本构成有弹性元件(各类弹簧,缓冲作用);减震元件(减震器,减震作用);导向机构(控制臂等…