两个链表的第一个公共结点——牛客offer
题目描述:
输入两个链表,找出它们的第一个公共结点。
题目分析:
只是数据域相同不是公共节点。公共结点代表该节点在两个链表中的数据域和指针域都是相同的,这意味着从该公共节点开始,后面的结点都是两个链表共有的,如图:

解题思路:
思路1:
从正序比较的角度来考虑:观察上图,链表1长度大于链表2,那么公共结点绝不可能存在于链表1比链表2多出来的那些结点中。基于这种想法,我们可以先求出两个链表的长度,然后现在长链表上遍历一段距离后,再开始同时遍历长链表和短链表并进行比较。
思路2:
从倒序比较的角度考虑:这个思路比较容易理解,因为两个链表的后面一部分是重复的,我们可以建立两个栈,将两个链表分别压入两个栈:
此时如果有栈是空的,说明无公共节点,返回null;
否则,循环取两个栈的栈顶元素进行比较:如果不相等,说明公共结点为该节点的下一个结点,否则循环直至有一个栈或两个栈为空终止:终止的原因有以下几条(1)如果两个栈都为空,说明是同一个链表,返回任意链表的头结点作为公共节点。例如{1,2,3} {1,2,3}(2)如果其中一个链表为空,说明短链表的全部元素都是和长链表共有的,则返回短链表的头结点。例如{1,2,3} {2,3}
测试:两者性能差不多,运行时间和占用空间相差无几。
代码实现:
思路1
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
Stack<ListNode> stack1=new Stack<ListNode>();
Stack<ListNode> stack2=new Stack<ListNode>();
ListNode walkNode=pHead1;
while(walkNode!=null){
stack1.push(walkNode);
walkNode=walkNode.next;
}
walkNode=pHead2;
while(walkNode!=null){
stack2.push(walkNode);
walkNode=walkNode.next;
}
//当两个链表都为空链表时,无公共结点,返回null
if(stack1.size()==0||stack2.size()==0){
return null;
}
while(!stack1.empty()&&!stack2.empty()){
ListNode pop1=stack1.pop();
ListNode pop2=stack2.pop();
if(pop1!=pop2){
return pop1.next;
}
}
//当两个栈同时为空时,且没有出现非公共结点,说明两个链表是完全一样的
if(stack1.size()==0&&stack2.size()==0){
return pHead1; //return pHead2;
}
//当stack1先空时,说明链表1的所有结点和链表2都是公共的
else if(stack1.size()==0){
return pHead1;
}
//当stack2先空时,说明链表2的所有结点和链表1都是公共的
else{
return pHead2;
}
}
思路2
获取链表长度:
public static int getLength(ListNode pHead){
ListNode walkNode=pHead;
int length=0;
while(walkNode!=null){
length++;
walkNode=walkNode.next;
}
return length;
}
寻找公共结点:
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int n1=getLength(pHead1);
int n2=getLength(pHead2);
int lenDiff=n1>n2?(n1-n2):(n2-n1);
ListNode walkNode1=pHead1;
ListNode walkNode2=pHead2;
//将walkNode1与walkNode2对齐
if(n1>n2){
while(lenDiff>0){
lenDiff--;
walkNode1=walkNode1.next;
}
}
else{
while(lenDiff>0){
lenDiff--;
walkNode2=walkNode2.next;
}
}
//遍历比较
while(walkNode1!=null){
if(walkNode1==walkNode2){
return walkNode1;
}
walkNode1=walkNode1.next;
walkNode2=walkNode2.next;
}
return null;
}
主函数测试:
public static void main(String[]args){
ListNode phead1=new ListNode(1);
ListNode node11=new ListNode(2);
ListNode node12=new ListNode(3);
ListNode phead2=new ListNode(4);
ListNode node21=new ListNode(5);
ListNode node13=new ListNode(6);
ListNode node14=new ListNode(7);
phead1.next=node11;
node11.next=node12;
node12.next=node13;
node13.next=node14;
phead2.next=node21;
node21.next=node13;
node13.next=node14;
System.out.print(FindFirstCommonNode(phead1,phead2).val);
}
两个链表的第一个公共结点——牛客offer的更多相关文章
- 九度OJ 1505 两个链表的第一个公共结点 【数据结构】
题目地址:http://ac.jobdu.com/problem.php?pid=1505 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例, ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- 《剑指offer》第五十二题(两个链表的第一个公共结点)
// 面试题52:两个链表的第一个公共结点 // 题目:输入两个链表,找出它们的第一个公共结点. #include <iostream> #include "List.h&quo ...
- 【剑指offer】两个链表的第一个公共结点,C++实现
原创文章,转载请注明出处! 博客文章索引地址 # 题目 #举例 如果两个单向链表有公共的节点,那么这两个链表从第一个公共结点开始,之后所有结点都是重合的,不可能再出现分叉.拓扑结构如下图所示: # 思 ...
- 剑指Offer - 九度1505 - 两个链表的第一个公共结点
剑指Offer - 九度1505 - 两个链表的第一个公共结点2013-11-24 20:09 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例 ...
- 编程算法 - 两个链表的第一个公共结点 代码(C)
两个链表的第一个公共结点 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入两个链表, 找出它们的第一个公共结点. 计算链表的长度, 然后移动 ...
- php实现找两个链表的第一个公共结点(实例演示)
php实现找两个链表的第一个公共结点(实例演示) 一.总结 因为是链表,第一个节点公共之后,后面所有的节点都公共了 画个图实例演示一下,会超清晰且简单 二.php实现找两个链表的第一个公共结点 题目描 ...
- 剑指Offer(三十六):两个链表的第一个公共结点
剑指Offer(三十六):两个链表的第一个公共结点 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...
- 【剑指offer】面试题 52. 两个链表的第一个公共结点
面试题 52. 两个链表的第一个公共结点 NowCoder 题目描述 输入两个链表,找出它们的第一个公共结点. Java 实现 ListNode Class class ListNode { int ...
随机推荐
- Java后台开发精选知识图谱
1.引言: 学习一个新的技术时,其实不在于跟着某个教程敲出了几行.几百行代码,这样你最多只能知其然而不知其所以然,进步缓慢且深度有限,最重要的是一开始就对整个学习路线有宏观.简洁的认识,确定大的学习方 ...
- 使用Xshell链接阿里云服务
1.下载Xshell,进入xshell官网 https://xshell.en.softonic.com/,选择免费版本进行下载,在该页面https://www.netsarang.com/zh/fr ...
- 深入学习golang中new与make区别
Go语言中的内建函数new和make是两个用于内存分配的原语(allocation primitives).对于初学者,这两者的区别也挺容易让人迷糊的.简单的说,new只分配内存,make用于slic ...
- java调用exe,及调用bat不成功的解决办法
开门见山的说,文件目录如下 想调用123.exe,但是尝试了几次调用不到,然后写了个bat.初始内容如下 @echo off D: cd test "123.exe" 双击可以运行 ...
- 性能分析 | JVM发生内存溢出的8种原因及解决办法
推荐阅读:史上最详细JVM与性能优化知识点综合整理 1.Java 堆空间 2.GC 开销超过限制 3.请求的数组大小超过虚拟机限制 4.Perm gen 空间 5.Metaspace 6.无法新建本机 ...
- <JavaScript>如何阅读《JavaScript高级程序设计》(一)
题外话 最近在看<JavaScript高级程序设计>这本书,面对着700多页的厚书籍,心里有点压力,所以我决定梳理一下..探究一下到底怎么读这本书.本书的内容好像只有到ES5...所以只能 ...
- CSS层叠样式表的层叠是什么意思
层叠的意思就是“继承”.“权重”.“覆盖”,通过良好的层级命名更好的实现效果,更少的代码,更多的功能,下面为大家详细介绍下,感兴趣的朋友不要错过 解答一: 层叠指的是样式的优先级,当产生冲突时以优 ...
- SQL Server 新建 数据库关系图 时弹出警告提示此数据库没有有效所有者,因此无法安装数据库关系图支持对象。
今天创建数据库关系图,发现提示此数据库没有有效所有者,因此无法安装数据库关系图支持对象.若要继续,请首先使用 数据库属性 对话框的文件页或 ALTER AUTHORIZAITION 语句将数据库所有者 ...
- hive端建表中文注释乱码
背景:mysql编码是utf-8,mysql中建库建表中文显示都正常,但在hive窗口中建表时字段中文注释均乱码的问题. 问题:hive中建表后字段中文注释显示异常. 1. 定位 mysql 端问题 ...
- k-means聚类分析范例程序
K-Means聚类算法原理参考以下链接: https://www.cnblogs.com/pinard/p/6164214.html 2. 传统K-Means算法流程 在上一节我们对K-Means的原 ...