题目:输入两个链表,找出它们的第一个公共结点。
分析:看到题目我们会想到最简单的一种方法,就是从头开始对两个链表进行遍历,对每一对结点进行比较,直到返回相同的结点,但是这种方法的时间复杂度相当高,如果链表的长度分别为m、n,那么时间复杂度为O(mn),这显然是很浪费资源的,在面试中也是不可取的。所以我们开始考虑第二种方法:如果是将链表从末尾向头部进行比较的话,那么可以有效降低时间复杂度,使用栈就能很好地解决这个问题,因为栈的先入后出的特点,使用栈就能解决这个问题,我们可以将每个结点先入栈,然后再出站进行对比,这样的话就能很好地解决这个问题。但是在这里我要使用第三种方法来解决这个问题,我们首先先来观察一下这个双链表的结构。
我们可以先求出两个链表的大小,然后将较长的链表先去掉多余的那一部分,然后两个链表再开始比较,这样的话时间复杂度为O(m+n),这是一般面试可以接受的一种算法
public class FindFirstCommonNode {
//这是求出链表长度的函数,返回链表长度
public int getLength(Node node){
int length=0;
if(node.next!=null){
node=node.next;
length++;
}
return length;
}
public Node FindFirstCommonNode(Node node1,Node node2){
//首先确定两个链表的长度
int length1=getLength(node1);
int length2=getLength(node2);
int nlength=0;
Node pNode1=null;
Node pNode2=null;
if(length1>length2){
nlength=length1-length2;
pNode1=node1;
pNode2=node2;
}
else{
nlength=length2-length1;
pNode1=node2;
pNode2=node1;
}
//先在长链表上走几步,再对两个链表进行比较
for(int i=0;i<nlength-1;i++){
pNode1=pNode1.next;
}
//两个链表开始比较
while((pNode1!=null)&&(pNode2!=null)&&(pNode1!=pNode2)){
pNode1=pNode1.next;
pNode2=pNode2.next;
}
//得到第一个公共结点
Node newNode=pNode1;
return newNode;
}
}