【手撕OJ题】——160. 相交链表

news2024/9/30 9:34:25

目录

  • 🕒 题目
  • ⌛ 方法① - 遍历记录链表长度
  • ⌛ 方法② - 双指针

🕒 题目

🔎 160. 相交链表【难度:简单🟢】
🔎 面试题 02.07. 链表相交
🔎 剑指 Offer 52. 两个链表的第一个公共节点

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

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

在这里插入图片描述

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

  • 示例 1:

在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

  • 示例 2:

在这里插入图片描述

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,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
  • 1 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA] == listB[skipB]

进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?

⌛ 方法① - 遍历记录链表长度

💡 思路:首先需要确定有没有相交,即确定尾结点的地址是否相同。之后找出交点,并求出LenA和LenB的长度。长链表先走差距步,后再同时走,第一个相等就是所求的交点,因为已经判断了是否相交。

代码实现如下:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
	if (headA == NULL || headB == NULL){  
        return NULL;	// 只要有一个是空链表,就一定不会相交
    }
    
    struct ListNode *curA = headA, *curB = headB;
    int LenA = 0; 
    int LenB = 0; 

    // 计算链表A的长度
    while (curA) {
        curA = curA->next; // 移动到下一个节点
        LenA++; // 长度加1
    }

    // 计算链表B的长度
    while (curB) {
        curB = curB->next; // 移动到下一个节点
        LenB++; // 长度加1
    }

    // 如果链表A和链表B的尾节点不相同,则没有交点
    if (curA != curB) {
        return NULL; // 返回NULL,表示没有交点
    }

    // 确定哪个链表较长,并将其设置为longList,另一个设置为shortList
    struct ListNode *longList = headA, *shortList = headB;
    if (LenA < LenB) {
        longList = headB; // 链表B较长,设置为longList
        shortList = headA; // 链表A较短,设置为shortList
    }

    // 计算两个链表长度差值
    int gap = abs(LenA - LenB);

    // 将longList指针向前移动长度差值的距离
    while (gap--) {
        longList = longList->next;
    }

    // 同时移动longList和shortList,直到它们相遇
    while (longList != shortList) {
        longList = longList->next; // 移动longList
        shortList = shortList->next; // 移动shortList
    }

    // 返回相遇的节点(即交点),如果没有交点,则返回NULL
    return longList;
}

⌛ 方法② - 双指针

💡 思路:分别指向两个链表的头节点,循环这个链表,之后再去循环另一个链表。分为两种情况:一种是没有交点,循环之后就返回 NULL;另一种是有交点。实际结果上,双指针各循环了链表A和链表B的并集一次。

代码实现如下:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    // 如果任意一个链表为空,则没有交点
    if (headA == NULL || headB == NULL) {
        return NULL;
    }

    struct ListNode *curA = headA;
    struct ListNode *curB = headB;

    // 当两个指针不同步时,继续循环
    while (curA != curB) {
        // 如果curA到达链表A的末尾,则重置到链表B的头部
        curA = (curA == NULL) ? headB : curA->next;
        // 如果curB到达链表B的末尾,则重置到链表A的头部
        curB = (curB == NULL) ? headA : curB->next;
    }

    // curA和curB要么同时为空(没有交点),要么同时指向交点
    return curA;
}

❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页

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

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

相关文章

hadoop集成spark(spark on yarn)

文章目录 hadoop集成spark&#xff08;spark on yarn&#xff09;下载spark软件包spark文件设置spark-env.shworkers 环境变量设置发送spark到其余机器启动spark hadoop集成spark&#xff08;spark on yarn&#xff09; 在hadoop搭建完成的前提下&#xff0c;集成spark&#x…

【面试题系列Vue02】Vue Router 路由都有哪些模式?各模式之间有什么区别?

官方解析 Vue Router 路由有三种模式&#xff1a; hash 模式&#xff1a;使⽤ URL 中的 hash&#xff08;即 # 后面的内容&#xff09;来作为路由路径。 在这种模式下&#xff0c;页面不会重新加载&#xff0c;只会更新 hash 值&#xff0c;并触发路由变化&#xff0c;从而渲…

c语言杂谈系列:模拟虚函数

从整体来看&#xff0c;笔者的做法与之前的模拟多态十分相似&#xff0c;毕竟c多态的实现与虚函数密切相关 废话少说&#xff0c;see my code&#xff1a; kernel.c#include "kernel.h" #include <stdio.h>void shape_draw(struct shape_t* obj) {/* Call dr…

气膜粮仓:卓越的抗风雪能力与高性能材料—轻空间

在粮食储存领域&#xff0c;气膜粮仓以其卓越的抗风雪能力和高性能材料成为了现代农业的首选。其独特的设计和先进的材料使其在各种极端天气条件下依然能够保证粮食的安全和品质。 强抗风雪能力&#xff0c;保障粮仓安全 气膜粮仓采用了创新的结构设计&#xff0c;能够有效抵御…

Selenium + Python 自动化测试19(补充-读取各种文件数据操作)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了数据驱动测试中如何完成重复的测试实例&#xff0c;今天我们补充一些读取各种文件的方法。 本篇文章我们讨论一下如何使用读取txt、CSV、Excel文件&#xff0…

burpsuite xssValidator插件(xss插件)

安装 1. 商城安装插件 2. 安装环境 Download PhantomJShttps://phantomjs.org/download.htmlGitHub - NetSPI/xssValidator: This is a burp intruder extender that is designed for automation and validation of XSS

halcon1

Halcon安装&#xff1a;halcon介绍&#xff1a; 德国MVtec公司开发的一套完善的标准的机器视觉算法包。底层功能算法多&#xff0c;运算性能快。halcon不能提供相应的界面编程需求&#xff0c;需要和vs一起才能构成一套完整软件。 软件界面 halcon数据类型 Halcon的数据类型主…

Hugo博客搭建

Hugo 构建 Hugo 安装 下载 安装包hugo version 查看是否安装成功 生成站点基础框架 进入自己指定文件夹下执行 hugo new site solejay-blog创建仓库 cd solejay-blog git init主题配置 进入 Hugo 主题页面 选择主题并下载 个人喜欢的主题&#xff1a;meme、newsroom、gal…

mac安装java17(jdk17)

1. 下载jdk17 官网下载&#xff1a;https://www.oracle.com/java/technologies/downloads 2. 直接安装 安装完后目录会存放在下面目录下 /Library/Java/JavaVirtualMachines 111111deMBP JavaVirtualMachines % ls jdk-11.0.227 jdk-17.jdk 3. 如果你已经安装过java&#…

【MobaXterm】查找输出结果的关键字

要求&#xff1a; 在MobaXterm终端的输出结果 查找关键字 解决&#xff1a; 菜单栏终端->在终端中查找 Terminal -> Find in terminal

智慧水务项目(七)vscode 远程连接ubuntu 20.04 服务器,调试pyscada,踩坑多多

一、说明 以前用过pycharm&#xff0c;远程连接还可以&#xff0c;但是vscode用以前还可以&#xff0c;就用它开发python了&#xff0c;想搞个远程&#xff0c;源码直接放服务器上&#xff0c;能远程调试&#xff0c;其实也很方便的&#xff0c;结果第一次还成功了&#xff0c;…

【机器翻译方向】数据集合集!

本文将为您介绍经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 QUAK 发布方&#xff1a; Upstage高丽大学 发布时间&#xff1a; 2022 韩英合成机器翻译质量预测数据 (韩英神经机器翻译的一个合成质量估计数据集&#xff0c;QUAK) 是指韩语句子和…

erlang学习:erlang学习:书上案例22.6练习题3

初步实现了书上案例第二&#xff0c;三问的要求&#xff0c;对输出结果有部分偏差&#xff0c;没有实现对已完成任务状态的记录&#xff0c;因此已完成任务输出无论如何都是0&#xff0c;明天会在record中加一个字段进行已完成任务状态的记录 (2) 添加一个名为job_centre:stati…

业绩回暖的小鹏,何时能够迈过月销2万的“及格线”?

古罗马哲学家塞涅卡在他的《论天命》中曾写下这么一句话&#xff1a;“英勇的士兵能够从战斗的胜利中获得喜悦&#xff0c;而伟大的人能够从逆境中得到欢乐。” 对于企业来说&#xff0c;身处逆境不一定能得到欢乐&#xff0c;但是走出逆境一定振奋人心。 8月20日&#xff0c…

【原创教程】电气电工10:接压线端子

电气电工这些知识点,我们描述的比较细,虽然看起来比较简单,但是它是后面我们技能提升的基础,如果我们后面学电气工程师相关知识,这些都属于基本功。 接着我们来看一下接线端子 一、接线端子 接线端子的介绍: 接线端子是一种用于连接电线的设备,它能够将电线的导体与…

vue3 bug记录

项目场景&#xff1a; vue2.7 使用vue的ref&#xff0c;报错 Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option. 原因分析&#xff1a; 表单组件使用了同名的ref&#xff0c;需要删掉

基于Modbus的MFC智能控制

1. 系统概述 利用LabVIEW通过Modbus 485协议实现对七星&#xff08;Sevenstar&#xff09;品牌质量流量控制器&#xff08;MFC&#xff09;的智能化控制。该系统将自动控制多个MFC的流速&#xff0c;实时监控其状态&#xff0c;并根据需要进行调整。 2. 硬件配置 MFCs: 七星品…

qt+ffmpeg报错non-existing PPS 0 referenced,如何解决???

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

LeetCode61.旋转链表

本题有两种做法&#xff1a;迭代和递归 本题的本质是&#xff1a;将链表中后k个结点变为前k个&#xff0c;然后将头结点连接到尾节点 迭代 考察知识&#xff1a; 边界条件判断链表倒k结点寻找Get思想&#xff1a;结环 /*** Definition for singly-linked list.* public cla…

基于51单片机的自动窗帘控制proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1l7MGgoPD5Q58ANR1djYWow 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…