leetcode刷题160 相交链表 Intersection of Two Linked Lists(简单) Python Java

将一个单向链表拆分成两个java实现 常见的一道笔试题:链表拆分,将一个单向链表和拆分成两个,如下所示:原始链表:1—>2—>3—>4—>5—>6—>7拆分后链表A:1—>3—>5—>7拆分后链表B:2—>4—>6思路:定义两个头节点,作为新链表的头,分别指向原链表的前两个元素再定义两个浮动,初始值分别指向新链表的头结点然后交替遍历原始节点,将各自的next赋值给新链表待遍历到最后,需要为两个新链表指定尾节点,即赋值为null最后退出循环。... 阅读详情

题目描述:

编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表:

在节点 c1 开始相交。

 

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 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
输出:Reference of the node with value = 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。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

 

解题思路:

(1)判断两个链表的尾节点是否相同,如果尾节点不相同的话,一定是没有相交,也就没有交点

(2)在遍历走到尾节点的同时,可以顺便计算链表的长度

(3)比较两个链表的长度,如果存在一个链表比另一个长一些的话,那么需要从长度相等的地方开始进行比较是否有相同节点,长链表的指针先向后移动lenA-lenB。然后两个链表一起往后走,若结点相同则第一个相交点。


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None
 
class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        lenA,lenB = 0,0 # 求链表各自的长度
        # 复制两个链表,不能直接对原链表进行操作
        pA = headA
        pB = headB
        # 求长度的具体操作
        while pA:
            pA = pA.next
            lenA += 1
        while pB:
            pB = pB.next
            lenB += 1
        # 此时指针已经都走到了两个链表的末端,如果两个链表的尾节点不同的话,那么肯定是没有相交,也就没有公共节点的,直接输出None
        if pA != pB:
            return None
        
        pA = headA # 指针再次回到起点
        pB = headB
        # 如果链表1的长度比较长
        if lenA > lenB:
            for i in range(lenA - lenB):
                pA = pA.next
        # 如果链表2的长度比较长
        else:
            for i in range(lenB - lenA):
                pB = pB.next
        
        while pA != pB: # 依次往后走
            pA = pA.next
            pB = pB.next
        
        return pA

 

以下是Java版本:

这道求两个链表的交点题要求执行时间为O(n),则不能利用类似冒泡法原理去暴力查找相同点,事实证明如果链表很长的话,那样的方法效率很低。我也想到会不会是像之前删除重复元素的题一样需要用两个指针来遍历,可是想了好久也没想出来怎么弄。无奈上网搜大神们的解法,发觉其实解法很简单,因为如果两个链长度相同的话,那么对应的一个个比下去就能找到,所以只需要把长链表变短即可。具体算法为:分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
                if (headA == null || headB == null) return null;
        int lenA = getLength(headA), lenB = getLength(headB);
        if (lenA > lenB) {
            for (int i = 0; i < lenA - lenB; ++i) headA = headA.next;
        } else {
            for (int i = 0; i < lenB - lenA; ++i) headB = headB.next;
        }
        while (headA != null && headB != null && headA != headB) {
            headA = headA.next;
            headB = headB.next;
        }
        return (headA != null && headB != null) ? headA : null;
    }
    public int getLength(ListNode head) {
        int cnt = 0;
        while (head != null) {
            ++cnt;
            head = head.next;
        }
        return cnt;
    }
}

这道题还有一种特别巧妙的方法,虽然题目中强调了链表中不存在环,但是我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路真的很巧妙,而且更重要的是代码写起来特别的简洁,参见代码如下:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) return null;
        ListNode a = headA, b = headB;
        while (a != b) {
            a = (a != null) ? a.next : headB;
            b = (b != null) ? b.next : headA;
        }
        return a;
    }
}

 

Leetcode 160. Intersection of Two Linked Lists-找到两个链表的第一个公共节点 --剑指offer37 可以发现两个链表在第一个节点重合之后不会再分开了 简单多说一句不会分开的原因,因为单向链表的节点只有一个nextNode指向下一个节点,那么如果该节点重合了,那么后面的节点一定是同一个。 一般这种问题要用两个类似指针的东西,一个先走,一个后走 所以我们先遍历找到两个链表的长度m和n,如果m大,m比n大多少,比如说k,那么先让m先走k步,然后n和m再一起走。 clas 阅读详情

相关推荐

CASS3D实战:高效三维房屋与地形采集绘制技巧

本文详细介绍了CASS3D在三维房屋与地形采集绘制中的高效技巧,包括智能绘房功能、不规则结构处理、特殊构件快速绘制及地形数据采集策略。通过实战案例和进阶操作指南,帮助用户快速掌握CASS3D的核心功能,提升三维采集与绘制效率。

weixin_29216049的博客 866

数据结构实验之链表五:单链表的拆分

Description 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数。两个子链表中数据的相对次序与原链表一致。 Input 第一行输入整数N;; 第二行依次输入N个整数。 Output 第一行分别输出偶数链表与奇数链表的元素个数; 第二行依次输出偶数子链表的所有数据; 第三行依次输出奇数子链表的所有数据。 Sample Input 10 1 3 22 8 15 999 9 44 6 1001 Output ..

qq_42107348的博客 1518

西门子RS485自由口通信Modbus RTU 通信协议

部分西门子的RS485模块不能使用西门子自带的Modbus RTU通信指令,需要通过自己拼接、发送、接收和解析报文完成Modbus RTU通信。通过多次尝试完成该功能: #R_TRIG_Instance(CLK := #触发, Q => #触发上升沿); IF #触发上升沿 THEN // 触发后先将读取完成复位 #读写完成 := 0; END_IF; CASE #功能码 OF 1: // 线圈状态读取 ; 2:

qq_20792765的博客 1万+

C语言实现:将链表 A 分解成两个链表

C语言实现将链表A按奇偶分为两个列表

weixin_49191101的博客 1123

UReport2 报表设计器 在线表格

UReport2官网 一、UReport2报表设计器 UReport2是一个开源的可视化报表设计器,功能强大,操作简单,可以实现复杂的报表统计,有各种各样的导出和打印功能,支持导入Excel表格! 1、报表设计器 2、设计一个简单的用户列表展示 二、可编辑表格 扩展了layui的表格,支持多元化数据编辑(单选,多些、日期、下拉联动),开发简单、高效、便捷。有了它就可以轻松开发类似进销存系统的表格录入功能了,用户拿来即用! 三、主从表录......

ejinxian的专栏 2万+

Qt界面编程(三)—— 父子关系、对象树、信号和槽(自定义信号和槽、Qt5与Qt4的写法)

Qt框架默认提供的标准信号和槽不足以完成我们日常应用开发的需求,比如说点击某个按钮让另一个按钮的文字改变,这时候标准信号和槽就没有提供这样的函数。但是Qt信号和槽机制提供了允许我们自己设计自己的信号和槽。声明在类的signals域下没有返回值,void类型的函数只有函数声明,没有定义可以有参数,可以重载通过emit关键字来触发信号,形式:emit object->sig(参数);

此心光明事上练的博客 1695

将一个单链表按照奇偶位置分解成两个单链表(空间复杂度最小)

将一个单链表按照奇偶位置分解成两个单链表(空间复杂度最小) 算法思想:函数的参数采用单链表的引用,返回值类型为链表,返回其中一个链表。 创建一个新的头结点,并且将形参传过来的链表置空,开始遍历,设置一个计数器,如果为奇数将节点添加到链表A的尾部,如果为偶数添加到链表B的尾部。具体实现代码如下。 #include<iostream> #include"linklist.h"//自己写的头文件 using namespace std; //将一个带头...

许你一片梁城的博客 5438

保姆级教程:在Ubuntu 22.04上搞定PX4 V1.14 + ROS2 Humble的HITL仿真(避坑实录)

本文提供在Ubuntu 22.04上配置PX4 V1.14与ROS2 Humble的HITL仿真环境的详细教程,涵盖环境准备、固件编译、QGroundControl配置、ROS2通信设置及联调测试。特别针对版本兼容性、Gazebo插件构建和MicroDDS配置等常见问题提供避坑指南,帮助开发者高效搭建无人机仿真系统。

weixin_30836759的博客 1001

《数据结构》将一个带头结点的单链表分解成两个单链表

将一个带头结点的单链表分解成两个单链表 题目描述: /* 设计一个算法,将一个带头结点的单链表分解成两个具有相同结构的 链表B和C,其中B白哦的结点为A中小于0的结点,C表的结点为A中大于0 的结点, 要求B和C 仍利用A表的结点。 (A表的元素都是非0元素) */ 算法思想:‘ 假设原来的连败哦是LA,将La,分解成LB和LC,首先需要生成两个头结点,LB和LC;设置

千言万语ROOM 2万+

汇川Easy系列斜坡函数功能块(支持状态输出)

IN rSetValue REAL 0.000000 0.000000 不保持 目标值 1IN rMaxValue REAL 0.000000 0.000000 不保持 最大目标值 2IN rMinValue REAL 0.000000 0.000000 不保持 最小目标值 3IN rSmoothTime REAL 100.000000 100.0000 不保持 最小到最大值平滑时间 单位 秒 4IN diTs DINT 10 10 不保持 函数调用周期采样时间中断时间 5。

RXXW_Dor的博客 455

LangGraph 实战教程:搭建一个智能办公多Agent协作平台

只存储必要的信息:不要把所有的原始数据都存储在状态中,比如销售数据可以存储在数据库或向量数据库中,状态中只存储数据的 ID 或摘要。使用类型提示:避免类型错误,提高代码的可维护性。支持增量更新:LangGraph 默认支持状态的增量更新(通过reduce函数),比如messages列表可以通过追加新消息的方式更新,而不是每次都重新创建整个列表。Normal Edge 的定义非常简单,只需要在StateGraph对象(稍后会详细讲解)上调用add_edge# 创建一个 StateGraph 对象。

SuperAGI2025 221

【数据结构】----将一个链表拆分为两个链表

《算法设计与分析》课堂作业 将一个链表拆分为两个链表 要求:将一个链表1、2、3、4、5、6、7、8、9、10 拆分为1、3、5、7、9 和2、4、6、8、10这两个链表 思路: 方法呢很简单,就是在第一个结点,看第二个是否存在,若存在,就把第二个加入链表2,并在链表1中删去,然后移动到第三个结点,同样的,看第四个存在不,若存在,就加入链表2并删去,继续在第五个结点,判断第六个。。。 ...

1900的博客 1万+

AI智算-K8s+vLLM & Ray:DeepSeek-r1 671B 满血版分布式推理部署实践

自从上次发布 【AI-智算】K8s+SGLang实战:DeepSeek-r1:671b满血版多机多卡私有化部署全攻略] 文章后,本次将演示另一个主流推理引擎工具——vLLM,结合K8s、LWS、Ray、Volcano等技术栈,部署DeepSeek-r1 671b 满血版分布式推理集群,并对比其与SGLang推理引擎的性能表现。

Kason_iWiki 1823

leetcode 160. intersection-of-two-linked-lists 相交链表 python3

时间:2020-7-1 题目地址:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/ 题目难度:Easy 题目描述: 编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:R

isabloomingtree的博客 199

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

leetcode 160. Intersection of Two Linked Lists

文章目录C++JavaPythonGo Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: begin to intersect at node c1. Example 1: Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [

wineandchord 218

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LeetCode 题解(216) : Intersection of Two Linked Lists

题目: Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ↘

449

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【LeetCode】Intersection of Two Linked Lists

1、【LeetCode】Intersection of Two Linked Lists  Total Accepted: 16034 Total Submissions: 58142 My Submissions Question Solution  Write a program to find the node at which the intersection of two singl

wangzq的专栏 849

leetcode_160. Intersection of Two Linked Lists 找两个单链表的交集的起始位置

题目: Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ↘

qqzj_bupt的博客 398

[LeetCode] 160. Intersection of Two Linked Lists 求两个链表的交集

Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ↘ ...

weixin_30716141的博客 113

将一个带头结点的单链表分解为两个具有相同构造的链表B和C【数据结构】【单链表】

编写一个函数完成如下功能:将一个带头结点的单链表分解为两个具有相同构造的链表B和C,其中B表的节点为A表中值小于0的节点,而C表的节点为A表中值大于0的节点(链表A中的元素为非零整数,要求B、C表利用A表的节点)。 要求,在主函数中调用上面的函数测试。 提示:还需要定义其他函数,比如初始化链表,构造单链表,输出单链表。

weixin_69200869的博客 1415

LeetCode # 725 分隔链表

给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分。 每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 null。 这k个部分应该按照在链表中出现的顺序进行输出,并且排在前面的部分的长度应该大于或等于后面的长度。 返回一个符合上述规则的链表的列表。 举例: 1->2->3->4, k = 5 // 5 结果 [ [1], [2], [3], [4], null ] 示例 1: 输入: root = [1,

婷子的博客 267

数据结构单链表转置和单链表拆分成两个单链表

先声明:本人是个初学者,本博客全为我自己写的,只是作为个人学习记录使用,很有可能不够规范或漏洞百出,请多包涵。 接下来贴一下题目要求: 首先先创建单链表: #include<stdio.h> #include<malloc.h> typedef int ElemType; typedef struct LNode { ElemType data; struct LNode* next; }LNode, * LinkList; //LNode*就是LinkLis..

m0_52461904的博客 1000

[单链表] 链表分割

链表分割:现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。 基本思想: 1.新建两个链表,一个放小于x值的结点,一个放大于x的结点 2.用a1,a2,b1,b2分别标记这两个链表的头和尾 3.用cur遍历原链表,以头插法把各个结点放到相对应的新链表中 4.分析新的两个链表是否有空的情况,若不为空,则把第一个链表的尾拼接到第二个链表的头 5.最后一个结点的next置空 public cl.

Darling_sheeps的博客 667

c语言链表拆分,C语言拆分链表程序

创建一个链表,并这个链表拆分成为两个链表的示例程序,将以下代码保存到一个源文件中:split_linked_list.c, 如下所示 –#include #include struct node { int data; struct node *next; }; struct node *even = NULL; struct node *odd = NU...

weixin_34738304的博客 573

线性表练习之Example020-将一个单链表拆分成两个链表,一个顺序一个倒序

设 `C = {a1, b1, a2, b2, ..., an, bn}` 为线性表,采用带头结点的 `hc` 单链表存放,设计一个就地算法,将其拆分为两个线性表,使得 `A = {a1, a2, ..., an}`,`B = {bn, ..., b2, b1}`。

二木成林 4218
上一篇: leetcode刷题155 最小栈 Min Stack(简单) Python Java
下一篇: leetcode刷题169 求众数 Majority Element(简单) Python Java
SpringRolls
博客等级 码龄9年 73粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值