题解 | #两个链表的第一个公共结点#
两个链表的第一个公共结点
https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46
这道题有些面向结果编程了qaq,写出来后好多测试点过不去,然后就面向结果了qaq
我的思路是,从链表的尾部往前比较两个链表各自的节点,如果一开始节点的地址不同说明是不同的节点,则两个链表没有共同的节点;如果一开始节点的地址是相同的,然后往前遍历的过程中发现了有不同地址的节点,则说明上一个遍历到的节点就是共同节点的第一个。
需要注意的特殊点有
- 两个链表中有一个链表是NULL的情况;
- 两个链表有一个链表的头节点就是共用节点,甚至两个链表的头节点均是公用节点;
对于第一种情况,毋庸置疑return NULL即可,但是对于第二种情况的判断有些麻烦
我们前面提到过,我们是从后往前遍历的,我们使用一个pub_x意思是倒数第pub_x个节点,则当pub_x等于链表的长度时,说明到达头节点了,这样将头节点return回去即可。
我们只需要在每遍历一个节点给pub_x执行++操作即可。
int getlength(struct ListNode* head)
{
int len = 0;
while(head!=NULL)
{
len++;
head = head->next;
}
return len;
}
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
// write code here
struct ListNode* p1 = pHead1;
struct ListNode* p2 = pHead2;
int len1 = getlength(p1);
int len2 = getlength(p2);
int pub_x = 1;
struct ListNode* output = NULL;
while(1)
{
struct ListNode* output1 = pHead1;
for(int i=0;i<len1-pub_x;i++)
{
output1 = output1 -> next;
}
struct ListNode* output2 = pHead2;
for(int i=0;i<len2-pub_x;i++)
{
output2 = output2->next;
}
if(output1!=NULL&&output2!=NULL)
{
if(output1==output2)
{
output = output1;
printf("%d\n", output->val);
}
if(output1!=output2||pub_x==len1||pub_x==len2)
{
return output;
}
}
if(output1==NULL||output2==NULL)
{
return NULL;
}
pub_x++;
}
}
