题目连接:
两个链表的第一个公共结点_牛客题霸_牛客网 (nowcoder.com)
题目描述:
描述
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。
输入描述:
输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,第三段是第一个链表和第二个链表的公共部分。 后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2。
返回值描述:
返回传入的pHead1和pHead2的第一个公共结点,后台会打印以该节点为头节点的链表。
题目解法:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
*BM10 两个链表的第一个公共结点
描述
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。
(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
1-2-3
\_6_7
/
4-5
输入描述:
输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,
第三段是第一个链表和第二个链表的公共部分。
后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2。
返回值描述:
返回传入的pHead1和pHead2的第一个公共结点,后台会打印以该节点为头节点的链表。
*/
/**************************code*****************************************/
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
int list1Count = 0, list2Count = 0;
struct ListNode *tmp, *longList, *shortList; //声明长短链表指针
tmp = pHead1; //得到pHead1的长度
while(tmp){
list1Count++;
tmp = tmp->next;
}
tmp = pHead2; //得到pHead2的长度
while(tmp){
list2Count++;
tmp = tmp->next;
}
if(list1Count >= list2Count){ //将pHead1 pHead2放入对应的长短链表里面
longList = pHead1, shortList = pHead2;
}else{
longList = pHead2, shortList = pHead1;
}
//由公共部分是一样的,可以看作右对齐,此时将长链表的移动到和短链表一样长
for(int i=0; i<abs(list1Count-list2Count); i++){
longList = longList->next;
}
//由于公共部分节点的地址是一样的,直接判断长短链表当前节点的地址是否一致即可
while(longList && shortList){
if(longList == shortList){
return longList;
}
longList = longList->next;
shortList = shortList->next;
}
return NULL;
}
/**************************end******************************************/
int main ()
{
struct ListNode LNa3={3,NULL};
struct ListNode LNa2={2,&LNa3};
struct ListNode LNa ={1,&LNa2};
struct ListNode LNb2 ={5,NULL};
struct ListNode LNb ={4,&LNb2};
struct ListNode LNc2 ={7,NULL};
struct ListNode LNc ={6,&LNc2};
LNa3.next = &LNc, LNb2.next = &LNc;
///********************************************
struct ListNode LNd ={1,NULL};
struct ListNode LNe2 ={3,NULL};
struct ListNode LNe ={2,&LNe2};
struct ListNode LNf;
LNd.next = &LNf, LNe2.next = &LNf;
struct ListNode* ret = FindFirstCommonNode(&LNd, &LNe);
while(ret){
printf("-*-- %d \r\n", ret->val);
ret = ret->next;
}
return 0;
}