思考1:链表的相交是怎么样的?
要注意!上面这样是不对的,链表中每个节点只有一个next,他不可能同时存两个指针。 多个节点存一个节点的地址是ok的。
链表的相交一定是以上这种。Y字型
思考2:如何判断两个链表是否相交?
思路一:【暴力求解】
A链表所有节点依次取B链表找一遍(注意要比对地址,而不是比对值)
时间复杂度为:O(N²)
思路二:【找尾节点】
分别找到尾节点,尾节点地址相同就相交,尾节点地址不相同就不相交。
时间复杂度为:O(N)
思路三:【算长度差】
分别求出A和B的长度,长的先走差距步,再同时走,第一个相同的就是交点
时间复杂度为:O(N)
代码实现:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
int A=1;
int B=1;
struct ListNode *curA=headA;
struct ListNode *curB=headB;
int N=0;
while(curA->next)
{
A++;
curA=curA->next;
}
while(curB->next)
{
B++;
curB=curB->next;
}
if(curA != curB)
{
return NULL;
}
else
{
N=abs(A-B);
//假设法
struct ListNode *longlist=headA;
struct ListNode *shortlist=headB;
if(B>A)
{
longlist=headB;
shortlist=headA;
}
//
while(N--)
{
longlist=longlist->next;
}
while(longlist != shortlist)
{
longlist=longlist->next;
shortlist=shortlist->next;
}
return longlist;
}
}
注意这里用到的假设法,我们不需要判断A和B到底谁长,用longList和shortList分别存储一下,然后比较,让长的先走差距步,然后再一起走,当longList和shortList相等的时候停下来即可。
注意这里while里面的条件:要让他们停留在尾节点的位置,不能让他们继续往后面走了。因为如果用while(cur),当cur==NULL的时候,循环结束,这个时候A和B的cur都是NULL,下面比较就没有意义,就无法看出两者是否相交了! 所以我们这里用while(cur->next),使它停留在尾节点处,看next是否为空。