相交链表 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
题目
解析
题目要求
- 如果相交 就返回交点
- 如果不相交 就返回
NULL
思路
1.通过题目的描述我们可以知道,两个单链表相交只有一种形式
并不存在下面的的形式
我们已经明确了单链表相交的形式, 那我们要如何判断两个单链表相交呢
这里给出一种做法,如果两个单链表相交,那么它们的最后一个元素肯定是一样的
如上图,所以我们可以写出这样的代码来判断他们相不相交
这一步是找出最后的那个元素
while(tailA != NULL) // tailA 是指向单链表A头节点的指针
{
tailA = tailA->next;
}
while(tailB != NULL) // tailB 是指向单链表B头节点的指针
{
tailB = tailB->next;
}
这一步是判断最后的元素相不相等
if( tailA != tailB)
{
return NULL;
}
如果相等就说明这两个单链表是相交的 就可以进入下一步了
即: 如何返回第一个相交的交点?
分析:
如果这两个单链表的长度是相同的话,(假设这两个单链表是A,B),要找第一个相交的点就简单的多,直接让A的指针(指向头节点的)和B的指针(指向头节点的)一起走,边走边判断,如果不相等就继续走,如果相等就可以停下来返回当前节点的地址了。
如图A B 都走三步就到达 交点了
可是,一般情况下,这两个链表的长度都不相等,那咋办?
不相等就把它变成相等的嘛,让长的那个链表多走几步,走到和短的链表一样长,然后两个链表在一起走,这样就行了。
所以我们还要比较链表的长度还要算出长了多少
看代码
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)\
{
//替身
struct ListNode *tailA = headA;
struct ListNode *tailB = headB;
//计数
int lenA = 1, lenB = 1;
//找尾
while(tailA != NULL)
{
tailA = tailA->next;
++lenA;
}
while(tailB != NULL)
{
tailB = tailB->next;
++lenB;
}
if(tailA != tailB)
return NULL;
//确定谁长
struct ListNode* longList = headA;
struct ListNode* shortList = headB;
if(lenA < lenB)
{
longList = headB;
shortList = headA;
}
//长的多走几步
int gap = abs(lenA-lenB); //abs 是求绝对值的
while(gap--)
{
longList = longList->next;
}
//然后两个一起走找相等的
while(longList != shortList)
{
longList = longList->next;
shortList = shortList->next;
}
return longList;
}