题目描述
输入两个链表,找出它们的第一个公共结点。
如果两个单向链表有公共的结点,也就是说两个链表从某一结点开始,它们的m_pNext都指向同一个结点。但由于是单向链表的结点,每个结点只有一个m_pNext,因此从第一个公共结点开始,之后它们所有结点都是重合的,不可能再出现分叉。所以,两个有公共结点而部分重合的链表,拓扑形状看起来像一个Y,而不可能像X。
思路1:采用蛮力的方法:在第一个链表上顺序遍历每个节点,每遍历到一个节点的时候,在第二个链表上顺序遍历每个节点。如果第二个链表上的节点和第一个链表上的节点一样,就说明两个链表在节点上重合,于是就找到了公共的节点。而通常蛮力并不是好的方法。
思路2:如果两个链表有公共结点,那么公共结点出现在连个链表的尾部,如果我们从两个链表的尾部开始比较,最后一个系统的结点就是我们要找的结点,可是单链表无法做到(只能顺序遍历),于是想到用栈的方式去处理,分别建立两个栈,
这样两个链表的尾部都在住栈顶,根据栈顶的结点是否系统来找到最后一个相同的结点
思路3:给予思路2 的处理之所以是用栈因为同时遍历两个栈的尾结点。当两个链表的结点的长度不相同时,如果从头开始遍历,到尾结点的时间就不一致,更简单的办法:先得到两个链表的长度,知道哪个链表比较长,让长链表先走几个结点,接着在同时遍历即可
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int length1=getNodeLength(pHead1);
int length2=getNodeLength(pHead2);
int lengthDif=length1-length2;
ListNode pListHeadLong=pHead1;
ListNode pListHeadShort=pHead2;
if (length2>length1){
pListHeadLong=pHead2;
pListHeadShort=pHead1;
lengthDif=length2-length1;
}
for (int i=0;i<lengthDif;i++){
pListHeadLong=pListHeadLong.next;
}
while (pListHeadLong!=null&&pListHeadShort!=null&&(pListHeadLong!=pListHeadShort)){
pListHeadLong=pListHeadLong.next;
pListHeadShort=pListHeadShort.next;
}
ListNode pFirtsNode=pListHeadLong;
return pFirtsNode;
}
int getNodeLength(ListNode phead){
int nLength=0;
ListNode p=phead;
while (p!=null){
++nLength;
p=p.next;
}
return nLength;
}