本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目

  输入两个链表,找出它们的第一个公共结点。

思路

  蛮力法:遍历第一个链表的结点,每到一个结点,就在第二个链表上遍历每个结点,判断是否相等。时间复杂度为O(m*n),效率低;

  使用栈:由于公共结点出现在尾部,所以用两个栈分别放入两个链表中的结点,从尾结点开始出栈比较。时间复杂度O(m+n),空间复杂度O(m+n)。

  利用长度关系:计算两个链表的长度之差,长链表先走相差的步数,之后长短链表同时遍历,找到的第一个相同的结点就是第一个公共结点。

  利用两个指针:一个指针顺序遍历list1和list2,另一个指针顺序遍历list2和list1,(这样两指针能够保证最终同时走到尾结点),两个指针找到的第一个相同结点就是第一个公共结点。

测试算例 

  1.功能测试(有/无公共结点;公共结点分别在链表的中间,头结点和尾结点)

  2.特殊测试(头结点为null)

完整Java代码

//题目:输入两个链表,找出它们的第一个公共结点。

public class FirstCommonNodesInLists {
public class ListNode{
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
} //方法1:利用长度关系
public ListNode findFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
int length1 = getLength(pHead1);
int length2 = getLength(pHead2);
int lengthDif = length1-length2;
ListNode longList = pHead1;
ListNode shortList = pHead2;
if(lengthDif<0){
longList = pHead2;
shortList = pHead1;
lengthDif = -lengthDif;
}
for(int i=0;i<lengthDif;i++)
longList = longList.next;
while(longList!=null && longList!=shortList ){
longList=longList.next;
shortList=shortList.next;
}
return longList; //没有公共结点刚好是null
} private int getLength(ListNode head){
int len=0;
while(head!=null){
len++;
head=head.next;
}
return len;
} //方法2:两个指针,p1顺序遍历list1和list2;p2顺序遍历list2和list1;最终一定会相遇
public ListNode findFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
ListNode p1=pHead1;
ListNode p2=pHead2;
while(p1!=p2){
p1= p1==null ? pHead2 : p1.next;
p2= p2==null ? pHead1 : p2.next;
}
return p1;
}
}

  

收获

  1.由于有共同结点时,后面的链表是重合的,所以这道题关键是要保证最后同时遍历到达尾结点,因此就有了后面三种方法:

  利用栈的先进后出实现同时到达;

  利用长度关系,长链表先行几步,实现同时到达;

  两个指针同时遍历两个链表,一个先list1后list2,另一个则相反,也可以实现同时到达。

  

更多:《剑指Offer》Java实现合集  

  

【Java】 剑指offer(52) 两个链表的第一个公共结点的更多相关文章

  1. 剑指 Offer 52. 两个链表的第一个公共节点 + 链表 + 第一个公共结点 + 双指针

    剑指 Offer 52. 两个链表的第一个公共节点 Offer_52 题目详情 题解分析 可以使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结 ...

  2. 力扣 - 剑指 Offer 52. 两个链表的第一个公共节点

    题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...

  3. 【剑指offer】两个链表的第一个公共结点,C++实现

    原创文章,转载请注明出处! 博客文章索引地址 # 题目 #举例 如果两个单向链表有公共的节点,那么这两个链表从第一个公共结点开始,之后所有结点都是重合的,不可能再出现分叉.拓扑结构如下图所示: # 思 ...

  4. 每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点

    题目信息 时间: 2019-07-03 题目链接:Leetcode tag: 单链表 难易程度:简单 题目描述: 输入两个链表,找出它们的第一个公共节点. 示例: A: a1 -> a2 \ - ...

  5. 剑指 Offer 52. 两个链表的第一个公共节点

    题目链接 题目描述: 我的题解: 方法一:双指针法 思路分析: 声明两个指针p1,p2 分别指向链表A.链表B. 然后分别同时逐结点遍历 当 p1 到达链表 headA 的末尾时,重新定位到链表 he ...

  6. Go语言实现:【剑指offer】两个链表的第一个公共结点

    该题目来源于牛客网<剑指offer>专题. 输入两个链表,找出它们的第一个公共结点. Go语言实现: //长度长的先走个长度差,然后ab一起比较后面结点 //长度一样,公共结点可能在首结点 ...

  7. 剑指offer:两个链表的第一个公共结点

    题目描述: 输入两个链表,找出它们的第一个公共结点. 解题思路: 这道题一开始的题意不太理解,这里的公共结点,实际上指结点指相同,在题目不存在结点值相同的不同结点. 1. 最直接的思路是对链表一的每个 ...

  8. 剑指Offer 36. 两个链表的第一个公共结点 (链表)

    题目描述 输入两个链表,找出它们的第一个公共结点. 题目地址 https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tp ...

  9. 【剑指offer】两个链表的第一个公共结点

    一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n  List2 长度:b+n, 且 a&l ...

随机推荐

  1. HTML5的学习(三)HTML5标签

    3.HTML5新添加的标签 标签 描述 <article> 定义文章. <aside> 定义页面内容之外的内容. <audio> 定义声音内容. <bdi&g ...

  2. python - wmi模块学习(windwos硬件信息获取)

    获取windows操作系统的硬件信息 #!/usr/bin/env python # -*- coding: utf-8 -*- # http://www.cnblogs.com/liu-ke/ im ...

  3. java生成TXT

    1.由于公司需要生成如下格式TXT: var ovr_parameters={ "changeMainVideoList": [ ], "indexList": ...

  4. Box-Muller 与 ziggurat

    1. Ziggurat 算法与 Box-muller 算法的效率比较 2. Box-Muller a. 一般形式 因函数调用较多,速度慢,当u接近0时存在数值稳定性问题 先假设. 用Box-Mulle ...

  5. python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib

    python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib ...

  6. UML和模式应用5:细化阶段(8)---逻辑架构和UML包图

    1.前言 本章是从面向分析的工作过度到软件设计 典型的OO系统设计的基础是若干架构层,如UI层.应用逻辑(领域)层 本章简要考察逻辑分层架构和相关UML表示法 2.逻辑架构和层 逻辑架构 逻辑架构是软 ...

  7. Hyper-V虚拟机上安装一个图形界面的Linux系统

    这件事情呢,一直想干但又觉得太陌生和麻烦,无奈现在到了非装不可的时候,只好硬着头皮去装.在此之前,我不懂什么叫做虚拟机,linux也接触甚少.经过3天的折腾,终于装好了带有图形界面的linux(字符版 ...

  8. day1 diff命令递归比较目录下的文件

    一.diff实战 (1)递归比较文件夹下所有的文件及目录的不同 diff --brief -Nr dir1/ dir2/                               Reference ...

  9. Android用户界面开发:Fragment

    Android用户界面开发:Fragment 1:注意事项  3.0以前的Android 版本要使用FragmentActivity 来装载Fragment ,使用到support v4包.  3.0 ...

  10. Jquery hover方法使用及 mouseenter与mouseleave和 mouseover与mouseout的区别

    定义和用法 hover() 方法规定当鼠标指针悬停在被选元素上时要运行的两个函数. jQuery 1.7 版本前该方法触发 mouseenter 和 mouseleave 事件. jQuery 1.8 ...