当前位置: 首页 > news >正文

数据结构链表力扣例题AC(3)——代码以及思路记录

160. 相交链表

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

AC写法一

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//思路基本一样struct ListNode* curA = headA;struct ListNode* curB = headB;int lenA = 0,lenB = 0;//先计算两个的长度while(curA){curA = curA->next;lenA++;}while(curB){curB = curB->next;lenB++;}//遍历结束后回到头结点curA = headA;curB = headB;//计算差距,并开始走差距步,diff大小可以知道哪一个更长int diff = lenA - lenB;if(diff > 0) {while(diff > 0) {curA = curA->next;diff--;}} else if(diff < 0) {while(diff < 0) {curB = curB->next;diff++;}}//当两个不相等就继续走,但是要注意任意一个都不能为空while(curA && curB && curA != curB){curA = curA->next;curB = curB->next;}//如果没有相交,两个也都走到了空//如果相交了此刻停留的位置也正好是相交初始节点,直接返回return curA;
}

AC写法二

struct ListNode* curA = headA;struct ListNode* curB = headB;int lenA = 0,lenB = 0;//lenA和lenB最后计数都会少了一个//但这道题目的是为了计算差值//同时都少一个不会对结果有影响while(curA->next){curA = curA->next;lenA++;}while(curB->next){curB = curB->next;lenB++;}//如果尾节点不相同,就没有相交。直接返回if(curA != curB){return NULL;}//abs函数,计算绝对值int n = abs(lenA - lenB);struct ListNode* longList = headA, *shortList = headB;//上一步做了假设,如果假设不成立那就交换,后边就不用关心长的是哪条链表了if(lenB > lenA){longList = headB;shortList = headA;}//长的先走差距步while(n--){longList = longList->next;}while(longList != shortList){longList = longList->next;shortList = shortList->next;return longList;

代码思路

上述两种代码的基本思路是一样的,具体细微的差别已经标注在代码中,接下来进行陈述:

首先看题寻找相交节点,那么这个链表不可能是 X 型,因为节点只能存储一个节点地址,所以只能是 Y 型或者不想交是平行,这一点看题目就可以明白。

最容易想到的暴力法,双指针,一个指向链表A,一个指向链表B,lenA进行链表A的遍历,将每一个节点与lenB当前所指的节点进行比较看是否相等,都不相等则lenB指向下一个LenA再进行比较,这样的方法时间复杂度为O(N^2)

还有一种时间复杂度为O(N)的方法。观察 Y 型结构,假设有两个指针指向两条链表的开始同时开始走并进行比较,由于链表相交前长度可能不一样,不一样的时候两个指针不可能相遇,但如果要两个指针相遇,相交之前有部分必须对应,那现在就是解决如何使两个指针按照我们需要的对应起来了,当较长的链表先走,走到剩余部分和较短链表一样时,两个指针一起走就解决了这个问题,而这部分先走的就是两条链表的长度差,所以两个指针都遍历一遍链表得出各自长度(遍历的同时可以比较尾节点是否相同,不相同直接说明没有相交),然后相减得出长度差,就可以实现如有交点两个指针一定会相遇的情况了。

141. 环形链表

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

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

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

AC

bool hasCycle(struct ListNode *head) {struct ListNode* slow = head, * fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast){return true;}}return false;
}

代码思路

快慢指针绝绝绝绝绝绝!

环形链表难点在于不知道哪里开始的环,但是在环里,就没有前后之分,使用快慢指针,从头开始走,fast走两步slow走一步,当fast走进环的时候slow一定还在后边,但是当slow也进环以后,由于两者速度不一样,fast会追上slow,想象一下速滑运动中的套圈,而在环中的话,就一定会相遇。如果没有环,那么fast会指向空。只要思路正确并不难写。至于为什么while循环中还需要fast->next也不能为空,因为fast一次走两步,当fast指向尾节点的时候,没有fast->next->next.

为什么快指针每次走两步,慢指针走一步可以?

假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。当慢指针刚 进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。 此时,两个指针每移动一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情 况,因此:在满指针走到一圈之前,快指针肯定是可以追上慢指针的,即相遇。

快指针一次走3步,走4步,...n步行吗?

142. 环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

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

不允许修改 链表。

AC

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* slow = head, *fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast){struct ListNode* meet = slow;while(head != meet){head = head->next;meet = meet->next;}return meet;}}return NULL;
}

代码思路

说明:

        H为链表的起始点,E为环入口点,M与判环时候相遇点

设:

        环的长度为R,H到E的距离为L E到M的距离为X

        则:M到E的距离为R-X

在判环时,快慢指针相遇时所走的路径长度:

        fast:L+X + nR

        slow:L + X

注意:

        1.当慢指针进入环时,快指针可能已经在环中绕了n圈了,n至少为1

        因为:快指针先进环走到M的位置,最后又在M的位置与慢指针相遇

        2.慢指针进环之后,快指针肯定会在慢指针走一圈之内追上慢指针

        因为:慢指针进环后,快慢指针之间的距离最多就是环的长度,而两个指针在移动时,每次它们至今的距离都缩减一步,因此在慢指针移动一圈之前快指针肯定是可以追上慢指针的

而快指针速度是满指针的两倍,因此有如下关系是:

        2 * (L + X)=L + X + nR

        L+X = nR

        L = nR - X (n为1,2,3,4..,n的大小取决于环的大小,环越小n越大)

        极端情况下,假设 n=1,此时:L = R -X

即:一个指针从链表起始位置运行,一个指针从相遇点位置绕环,每次都走一步,两个指针最终会在入口点的位置相遇

思路二:将meet的下一个节点meet->next交给一个新指针newhead,然后将meet的next置空,meet->next = NULL,此刻就将题转化为了链表相交问题,但是这种写代码更为复杂,此处不做尝试

相关文章:

数据结构链表力扣例题AC(3)——代码以及思路记录

160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 AC写法一 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//思…...

C++初阶:容器适配器priority_queue常用接口详解及模拟实现、仿函数介绍

介绍完了stack和queue的介绍以及模拟的相关内容后&#xff1a;C初阶&#xff1a;容器适配器介绍、stack和queue常用接口详解及模拟实现 接下来进行priority_queue的介绍以及模拟&#xff1a; 文章目录 1.priority_queue的介绍和使用1.1priority_queue的初步介绍1.2priority_que…...

提取淘宝店铺联系方式的爬虫工具

随着电子商务的快速发展&#xff0c;淘宝成为了许多人购物的首选平台。而对于一些商家来说&#xff0c;获取淘宝店铺的联系方式是非常重要的&#xff0c;以便建立更加直接和有效的沟通渠道。本文将介绍一种基于Python的爬虫工具&#xff0c;可以帮助我们提取淘宝店铺的联系方式…...

Eureka服务搭建

1️⃣搭建服务 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>启动类加注解 EnableEurekaServer SpringBootApplication public…...

SORA技术报告

文档链接&#xff1a;https://openai.com/research/video-generation-models-as-world-simulators 文章目录 Video generation models as world simulatorsTurning visual data into patchesVideo compression networkSpacetime latent patchesScaling transformers for video …...

Python Web开发记录 Day1:HTML

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、HTML1、前端引入和HTML标签①前端引入②浏览…...

六、回归与聚类算法 - 模型保存与加载

目录 1、API 2、案例 欠拟合与过拟合线性回归的改进 - 岭回归分类算法&#xff1a;逻辑回归模型保存与加载无监督学习&#xff1a;K-means算法 1、API 2、案例...

Spring事务模板及afterCommit存在的坑

大家好&#xff0c;我是墨哥&#xff08;隐墨星辰&#xff09;。今天的内容来源于两个线上问题&#xff0c;主要和大家聊聊为什么支付系统中基本只使用事务模板方法&#xff0c;而不使用声明式事务Transaction注解&#xff0c;以及使用afterCommit()出现连接未按预期释放导致的…...

【区块链】联盟链

区块链中的联盟链 写在最前面**FAQs** 联盟链&#xff1a;区块链技术的新兴力量**联盟链的定义****联盟链的技术架构**共识机制智能合约加密技术身份认证 **联盟链的特点**高效性安全性可控性隐私保护 **联盟链的应用场景****金融服务****供应链管理****身份验证****跨境支付**…...

Oracle case when end和decode的区别

Oracle中的CASE WHEN和DECODE都是条件表达式&#xff0c;但它们在某些方面有所不同。 CASE WHEN&#xff1a; CASE WHEN是一个条件表达式&#xff0c;允许您基于条件返回不同的值。它具有以下结构&#xff1a; sql CASE WHEN condition1 THEN result1 WHEN condition2 THE…...

Java导出pdf格式文件

Java实现导出pdf &#xff5c;word &#xff5c;ppt 格式文件 controller层&#xff1a; ApiOperation("导出")GetMapping("/download")public void download(RequestParam("userId") Long userId ,HttpServletResponse response) {reportResul…...

Socket、UDP、TCP协议和简单实现基于UDP的客户端服务端

目录 Socket TCP和UDP区别 UDP&#xff1a;无连接&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工 TCP&#xff1a;有连接&#xff0c;可靠传输&#xff0c;面向字节流&#xff0c;全双工 无连接和有连接 可靠传输和不可靠传输 面向数据报和面向字节流…...

发布订阅模式:观察者模式的一种变体

发布-订阅模型&#xff08;Publish-Subscribe Model&#xff09;的底层机制通常基于观察者模式。 发布-订阅模型是观察者模式的一种变体。 在观察者模式中&#xff0c;主题&#xff08;或被观察者&#xff09;维护了一组观察者&#xff0c;当主题的状态发生变化时&#xff0c…...

TiDB离线部署、Tiup部署TiDB

先做tidb准备工作&#xff1a; 部署 TiDB 前的环境检查操作&#xff1a;TiDB 环境与系统配置检查 | PingCAP 文档中心 1.查看数据盘 fdisk -l &#xff08;2,3&#xff09;本人的分区已经是 ext4 文件系统不用分区&#xff0c;具体官方文档的分区&#xff1a; 4.查看数据盘…...

10GBase-T万兆电口模块助力数据中心实现高效数据传输

10GBase-T万兆电口模块一种高速、高效的网络连接解决方案&#xff0c;具有快速传输速度和稳定可靠的特点。它可以在数据中心中广泛应用&#xff0c;提供出色的网络性能和可扩展性&#xff0c;为数据中心的发展做出了重要的贡献。 一、10GBase-T万兆电口模块的特点与优势 高速传…...

使用Docker中部署GitLab 避坑指南

在容器化的世界中&#xff0c;Docker已经成为了我们部署和管理应用程序的首选工具。然而&#xff0c;在使用Docker部署GitLab时&#xff0c;我们可能会遇到一些问题&#xff0c;本文将为你提供一份详细的避坑指南。网上的教程有的都没说清楚&#xff0c;或者干脆是错的。摸索了…...

我的NPI项目之设备系统启动(八) -- Android14的GKI2.0开发步骤和注意事项

GKI是什么&#xff1f; Google为什么要推行GKI&#xff1f; GKI全称General Kernel Image。GKI在framework和kernel之间提供了标准接口&#xff0c;使得android OS能够轻松适配/维护/兼容不同的设备和linux kernel。 Google引入GKI的目的是将Framework和Kernel进一步的解耦。因…...

鼠标右键助手专业版 MouseBoost PRO for Mac v3.3.6中文破解

MouseBoost Pro mac版是一款简单实用的鼠标右键助手专业版&#xff0c;MouseBoost Pro for Mac只要轻点你的鼠标右键&#xff0c;就可以激活你想要的各种功能&#xff0c;让你的工作效率大幅度提高&#xff0c;非常好用。 软件下载&#xff1a;MouseBoost PRO for Mac v3.3.6中…...

React学习计划-react-hooks补充

React Hooks 1. 使用hooks理由 高阶组件为了复用&#xff0c;导致代码层级复杂生命周期的复杂 2. useState(保存组件状态) const [state, setstate] useState(initialState)3. useEffect(处理副作用)和useLayoutEffect(同步执行副作用) 使用方式&#xff1a; useEffect(…...

KTV点歌系统vue+springboot音乐歌曲播放器系统

目前现有的KTV点歌系统对于用户而言其在线点歌流程仍然过于繁琐&#xff0c;对于歌曲而言其系统安全性并不能保障。同时整套系统所使用的技术相对较为落后&#xff0c;界面不能动态化展示。相比较于其它同类型网站而言不能体现技术先进性。 1.2 项目目标 KTV点歌系统的后台开发…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...