本文参考自《剑指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. Docker入门03——Container

    1 启动容器 1.1 新建并启动 1.2 启动已终止容器 2 后台运行 3 终止 4 进入容器 5 导入和导出 5.1 导出 5.2 导入 6 删除 1 启动容器 1.1 新建并启动 docker r ...

  2. kali linux 安装QQ

    之前在kali上尝试过Wineqq2012,显示版本过低,放弃了.最近听说crossover比wine的支持要好,再次尝试. 1.下载 https://www.codeweavers.com/ 选择d ...

  3. 用NDK调用第三方库

    用NDK调用第三方库遇到不少坑,总结一下. 1.添加JNI目录 参考: http://www.cnblogs.com/lanqie/p/7442668.html 2.文件介绍: 其中:JniFacto ...

  4. char *与const char **函数参数传参问题

    传参方法 ## 函数 extern void f2 ( const char ** ccc ); const char ch = 'X'; char * ch_ptr; const char ** c ...

  5. mysql之 innobackupex备份+binlog日志的完全恢复【转】

    前言: MySQL的完全恢复,我们可以借助于完整的 备份+binlog 来将数据库恢复到故障点. 备份可以是热备与逻辑备份(mysqldump),只要备份与binlog是完整的,都可以实现完全恢复. ...

  6. git 使用https 和SSH 提交远程库小总结

    一.使用https提交远程库 首先已经git commit -m “注释” 本地仓库关联远程github服务器:git remote add origin  “https://XXXX.git” 提交 ...

  7. Mac Terminal 菜鸟篇之目录跳转命令

    以前一直都是使用Windows系统,连命令行都没怎么用过.来到了Mac,在某位大神的诱导下,我开始尝试使用Mac Terminal,下面总结的是一些简单的目录跳转命令(菜鸟级). 文件目录 首先要清楚 ...

  8. Android TimeAnimator

    TimeAnimator:提供了一个简单的回调机制,通过 TimeAnimator.TimeListener,在动画的每一帧处通知你.这个动画器没有时间,插值或是对象值设定.回调监听器为每一帧动画接受 ...

  9. Node.js随手笔记

    参考文章:https://blog.csdn.net/IronKee/article/details/83780857 安装nvm的方法: 如果已经单独安装了node,建议卸载,然后继续向下看. 直接 ...

  10. Linux C 结构体初始化三种形式

    最近看linux代码时发现了结构体 struct 一种新的初始化方式,各方查找对比后总结如下: 1. 顺序初始化教科书上讲C语言结构体初始化是按照顺序方式来讲的,没有涉及到乱序的方式.顺序初始化str ...