两个链表的第一个公共结点
题目:
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
示例:
输入:{1,2,3},{4,5},{6,7}
返回值:{6,7}
说明:第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的
输入:{1},{2,3},{}
返回值:{}
说明:2个链表没有公共节点 ,返回null,后台打印{}
解题思路:
假设一个链表比另一个链表长K个结点,我们先在长的链表上遍历K个结点,之后再同步遍历,此时我们就能保证同时到达最后一个节点。由于两个链表从第一个公共结点开始到链表的尾结点,这一部分是重合的,因此,他们肯定也是同时到达第一个公共结点的。于是在遍历中,第一个相同的结点就是第一个公共的结点。
根据这一思路,我们先要分别遍历两个链表,得到它们的长度,并求出两个长度之差。在长的链表上先遍历长度之差个结点,之后再同步遍历两个链表,直到找到相同的结点,或者一直到链表结束。
代码示例:
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*
* C语言声明定义全局变量请加上static,防止重复定义
*/
/**
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
// write code here
if(pHead1 == NULL || pHead2== NULL){
return NULL;
}
struct ListNode *p1 = pHead1;
struct ListNode *p2 = pHead2;
int len1=0,len2=0;
while(p1!=NULL){
p1 = p1->next;
len1++;
}
while(p2!=NULL){
p2 = p2->next;
len2++;
}
struct ListNode* longList,*shortList;
int dist;
if(len1>len2){
longList=pHead1;
shortList=pHead2;
dist=len1-len2;
}else{
longList=pHead2;
shortList=pHead1;
dist=len2-len1;
}
while(dist--)
longList=longList->next;
while(longList!=NULL){
if(longList==shortList)
return longList;
else{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;
}