题目描述
输入两个链表,找出它们的第一个公共结点。
解题思路:
看到这道题的时候,很多人的第一反应就是采用蛮力的方法:在第一个链表上顺序遍历每个节点,每遍历到一个节点的时候,在第二个链表上顺序遍历每个节点。如果第二个链表上的节点和第一个链表上的节点一样,就说明两个链表在节点上重合,于是就找到了公共的节点。而通常蛮力并不是好的方法。
从链表的定义可以看出,这两个链表是单链表,如果两个链表有公共节点,那么这两个链表从某一节点开始,它们的m_pNext都指向同一个节点,之后它们所有的节点都是重合的,不可能再出现分叉。所以拓扑形状看起来是Y型。如下图所示:
一个简单的方法是:首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第二次遍历的时候,先在较长的节点上走若干步,接着同时在两个链表上遍历,找到的第一个相同的节点就是它们的公共的节点。该算法的时间复杂度为:O(m+n)。
代码如下:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1==pHead2){
return pHead1;
}
int l1=getlength(pHead1);
int l2=getlength(pHead2);
if(l1>l2){
for(int i=0;i<(l1-l2);i++){
pHead1=pHead1.next;
}
}else{
for(int i=0;i<(l2-l1);i++){
pHead1=pHead1.next;
}
}
boolean f=true;
ListNode p=null;
while(f){
if(pHead1==null||pHead2==null){
return null;
}
if(pHead1==pHead2){
p=pHead1;
f=false;
}else{
pHead1=pHead1.next;
pHead2=pHead2.next;
}
}
return p;
}
public static int getlength(ListNode pHead){
int n=0;
while(pHead!=null){
n++;
pHead=pHead.next;
}
return n;
}
}