题目描述:

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

题目分析:

只是数据域相同不是公共节点。公共结点代表该节点在两个链表中的数据域和指针域都是相同的,这意味着从该公共节点开始,后面的结点都是两个链表共有的,如图:

解题思路:

思路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的更多相关文章

  1. 九度OJ 1505 两个链表的第一个公共结点 【数据结构】

    题目地址:http://ac.jobdu.com/problem.php?pid=1505 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例, ...

  2. C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告

    剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...

  3. 《剑指offer》第五十二题(两个链表的第一个公共结点)

    // 面试题52:两个链表的第一个公共结点 // 题目:输入两个链表,找出它们的第一个公共结点. #include <iostream> #include "List.h&quo ...

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

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

  5. 剑指Offer - 九度1505 - 两个链表的第一个公共结点

    剑指Offer - 九度1505 - 两个链表的第一个公共结点2013-11-24 20:09 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例 ...

  6. 编程算法 - 两个链表的第一个公共结点 代码(C)

    两个链表的第一个公共结点 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入两个链表, 找出它们的第一个公共结点. 计算链表的长度, 然后移动 ...

  7. php实现找两个链表的第一个公共结点(实例演示)

    php实现找两个链表的第一个公共结点(实例演示) 一.总结 因为是链表,第一个节点公共之后,后面所有的节点都公共了 画个图实例演示一下,会超清晰且简单 二.php实现找两个链表的第一个公共结点 题目描 ...

  8. 剑指Offer(三十六):两个链表的第一个公共结点

    剑指Offer(三十六):两个链表的第一个公共结点 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

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

    面试题 52. 两个链表的第一个公共结点 NowCoder 题目描述 输入两个链表,找出它们的第一个公共结点. Java 实现 ListNode Class class ListNode { int ...

随机推荐

  1. Configure vyatta

    Username: vyatta Password: vyatta 配置网卡: 编辑: configure 内部网络IP地址配置:192.168.0.1 set interfaces ethernet ...

  2. LeetCode 32. 最长有效括号(Longest Valid Parentheses)

    题目描述 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 "( ...

  3. fastadmin 全手动添加规则

    全手动的话 你需要在规则管理里面添加规则 然后角色组就可以设置权限了如果是自动的话 应该就都生成了权限设置 1.增删改查的规则也要添加哦 2.角色组勾选相应的规则 https://ask.fastad ...

  4. centos 如何查看命令是由哪个包提供的

    yum whatprovides */ifconfig Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile ...

  5. 处理输入为非对角阵的Clustering by fast search and find of density peak代码

    Clustering by fast search and find of density peak. Alex Rodriguez, Alessandro Laio 是发表在Science上的一篇很 ...

  6. BCNF/3NF的判断方法

    判断是否是 3NF 的条件: 对于 R 上的每个函数依赖 X->A (X 是关系 R 属性的一个子集,A 是 R 的一个属性) ,以下条件中的一个成立:1 X ∈ A2 X 是超码3 A 是 R ...

  7. Node安装配置

    下载安装nodejs后进行如下配置: 修改模块安装位置和缓存位置在要存放的位置手动新建全局目录node_global在要存放的位置手动新建缓存目录node_cache执行如下命令:npm config ...

  8. linux简单命令8---软件包安装

    1:使用yum安装,它不能包查询和包校验.它安装的是RPM格式文件.没有yum文件 ---------------------------------------------------------- ...

  9. 利用百度智能云结合Python体验图像识别(转载来自qylruirui)

    https://blog.csdn.net/qylruirui/article/details/94992917 利用百度智能云结合Python体验图像识别只要注册了百度账号就可以轻松体验百度智能云中 ...

  10. 包含min函数的栈、队列

    题目:定义栈的数据结构,请在该类型中实现一个能够得到栈/队列的最小元素的min函数.在该栈/队列中,调用min.入栈(入队列)及出栈(出队列)函数的时间复杂度都是O(1). 1. 包含min函数的栈 ...