如何判断两个单链表(无环)是否交叉

单链表相交指的是两个链表存在完全重合的部分,如下图所示

在上图中,这两个链表相交于结点5,要求判断两个链表是否相交,如果相交,找出相交处的结点。

分析

Hash法

如上图所示,如果两个链表相交,那么它们一定会有公共的结点,由于结点的地址或引用可以作为结点的唯一标识,因此,可以通过判断两个链表中的结点是否有相同的地址或引用来判断链表是否相交。

具体可以采用如下方法实现:

首先遍历链表head1,把遍历到的所有结点的地址存放到HashSet中;

接着遍历链表head2,每遍历到一个结点,就判断这个结点的地址在HashSet中是否存在,如果存在,那么说明两个链表相交并且当前遍历到的结点就是它们的相交点,否则直到链表head2遍历结束,说明这两个单链表不相交。

算法性能分析

由于这种方法需要分别遍历两个链表,因此,算法的时间复杂度为O(n1+n2)。

其中,n1与n2分别为两个链表的长度。

此外,由于需要申请额外的存储空间来存储链表head1中结点的地址,因此,算法的空间复杂度为O(n1)。

首尾相接法

主要思路:将这两个链表首尾相连(如把链表head1尾结点链接到head2的头指针),然后检测这个链表是否存在环,如果存在,则两个链表相交,而环入口结点即为相交的结点,如下图所示。

尾结点法

主要思路:如果两个链表相交,那么两个链表从相交点到链表结束都是相同的结点,必然是Y字形(如上图所示)。所以,判断两个链表的最后一个结点是不是相同即可。即先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交,这时记下两个链表的长度n1、n2,再遍历一次,长链表结点先出发前进|n1-n2|步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

代码实现

/*** 判断两个单链表(无环)是否交叉** @author Java后端技术栈 tian*/public class CommonLoopNode {   //找出交叉点   public static Node findOverlap(Node head1, Nodehead2) {       if (head1 == null || head1.next == null) {           return null;      }       if (head2 == null || head2.next == null) {           return null;      }       Node temp1 = head1.next;       Node temp2 = head2.next;       int n1 = 0, n2 = 0;       //遍历head1,找到尾节点,同时记录head1的长度       while (temp1.next != null) {           temp1 = temp1.next;           ++n1;      }       //遍历head2,找到尾节点,同时记录head2的长度       while (temp2.next != null) {           temp2 = temp2.next;           ++n2;      }       //head1与head2有相同的尾节点       if (temp1 == temp2) {           //长链表的先走|n1-n2|           if (n1 > n2) {               while (n1 - n2 > 0) {                   head1 = head1.next;                   --n1;              }          }           if (n2 > n1) {               while (n2 - n1 > 0) {                   head2 = head2.next;                   --n2;              }          }           while (head1 != head2) {               head1 = head1.next;               head2 = head2.next;          }           return head1;      } else {           //head1和head2没有相同的尾节点           return null;      }  }   public static void main(String[] args) {       int i = -1;       Node head1 = new Node();       head1.next = null;       Node head2 = new Node();       head2.next = null;       Node temp;       Node cur = head1;       Node p = null;       //构造第一个head1       for (; i 

运行结果

在上述代码中,由于构造的两个单链表相交于结点5,因此,输出结果中它们的相交结点为5。

如果还存在疑惑不清楚的,请结合代码和图一起看。

算法性能分析

假设这两个链表长度分别为n1、n2,重叠的结点的个数为L(0<L<min(n1,n2)),则总共对链表进行遍历的次数为n1+n2+L+n1-L+n2-L=2(n1+n2)-L。

因此,算法的时间复杂度为O(n1+n2)。

由于这种方法只使用了常数个额外指针变量,因此,空间复杂度为O(1)。

引申

如果单链表有环,如何判断两个链表是否相交。

1)如果一个单链表有环,另外一个没有环,那么它们肯定不相交。

2)如果两个单链表都有环并且相交,那么这两个链表一定共享这个环。

c++如何判断两个字符串是否相同?_链表 | 如何判断两个单链表(无环)是否交叉...相关推荐

  1. PHP两个字符串比较(人为出错),两字符串类型和数据表面相等,但strcmp()结果不为0...

    PHP中,比较两个字符串是否相等用:strcmp(): PHP strcmp() 函数 PHP String 函数 定义和用法 strcmp() 函数比较两个字符串. 该函数返回: 0 - 如果两个字 ...

  2. java字符串含有特殊字符_[Java教程]判断输入的字符串是否含有特殊字符和表情_星空网...

    判断输入的字符串是否含有特殊字符和表情 2017-07-27 0 reg = /[~#^$@%&!?%*]/gi; if (reg.test(postdata.Name.trim())) { ...

  3. c语言对比两个字符串相等,c语言中如何判断两个字符串相等

    可以使用库函数strcmp判断,具体如下: strcmp是C语言比较字符串的库函数,形式为int strcmp(char *a, char *b); 该函数会对a和b的每个字符,按照ascii码值比较 ...

  4. python比较两个字符串相似度_详解Python 字符串相似性的几种度量方法

    字符串的相似性比较应用场合很多,像拼写纠错.文本去重.上下文相似性等. 评价字符串相似度最常见的办法就是:把一个字符串通过插入.删除或替换这样的编辑操作,变成另外一个字符串,所需要的最少编辑次数,这种 ...

  5. java两个字符串 相隔天数_关于Java: Joda-Time时间中两个日期之间的天数

    我如何找到两个joda time DateTime实例之间的天数差异?如果开始时间是星期一,结束时间是星期二,那么不管开始和结束日期的小时/分钟/秒是多少,返回值都应该是1. 如果从晚上开始到早上结束 ...

  6. c语言求两个字符串的交集,用c语言求两个集合的交集,并集,差集

    满意答案 ibox5 2019.05.05 采纳率:54%    等级:11 已帮助:8963人 #include #include #include #define ARR_LEN 255/*数组长 ...

  7. 多组两两比较用什么检验方法_多组均数两两比较时,若不用q检验而用t检验,则:...

    当柴油机以正常负荷运转时,多组可能出现排烟的颜色是(). 冯友兰认为人生有四种境界,均数检验t检自然境界.均数检验t检功利境界.道德境界和天地境界,不同境界对应不同的人生目的.这四种境界意味着在生活中 ...

  8. 如何判断笔记本蓝牙硬件坏了_笔记本如何判断显卡硬件坏了 - 卡饭网

    怎么判断显卡性能有哪些细节 怎么判断显卡性能有哪些细节 现在,越来越多的用户在挑选笔记本时更重视显卡的性能,甚至胜于重视处理器性能,下面简单为大家介绍下,感兴趣的朋友不要错过. 显示芯片,显存位宽,显 ...

  9. mysql同时查两张表数据库表_如何同时查询两个数据库表?

    展开全部 sql多表关联查询跟条件查询大同小异,主要是要知道表与表之前的关系很重e69da5e6ba9062616964757a686964616f31333431353238要: 举例说明:(某数据 ...

最新文章

  1. ASP.NET管理状态的十种途径
  2. strom.yaml配置
  3. HomeKit推出已两年 但是苹果在智能家居上却被对手甩开了差距
  4. ghost一键还原如何使用
  5. mysql originator_MySQL中的事件调度器EVENT
  6. AB1601的波特率注意事项
  7. Docker使用阿里云docker镜像加速
  8. HBase最佳实践-读性能优化策略
  9. javascript --- event loop
  10. Linq 下的 Take() 方法内部机制是怎样的?
  11. PS2019摄影后期处理(二)
  12. JNDI配置原理详解
  13. jar 打包命令详解
  14. c#解析XML到DATASET及dataset转为xml文件函数
  15. win10 Eprime 2.0安装记录
  16. STM32红外接收分析
  17. 第三届“泰迪杯”数据分析职业技能大赛: 教育平台的线上课程智能推荐 (决赛候选)答辩PPT
  18. 推荐三款最佳的远程桌面管理工具
  19. linux的磁盘busy,Linux umount 报 device is busy 的处理方法
  20. 转:SDHC卡驱动及初始化

热门文章

  1. 企业文化:谦虚(谦逊,虚心)
  2. Oracle 11g xe版本---总结1
  3. P1091 合唱队形
  4. CompletableFuture 详解
  5. C++多重继承时调用相应的父类函数
  6. 在Visual Studio 2005下配置WinPcap开发环境
  7. 重写GridView支持数据筛选和自动排序功能
  8. BCG-MFC 库对《支持重新启动管理器》都做了些什么
  9. 大数据之-Hadoop3.x_MapReduce_排序概述---大数据之hadoop3.x工作笔记0114
  10. 大数据_Hbase-(知识点回顾)---Hbase工作笔记0010