C语言——相交链表

一、题目分析

判断两个链表相交,就要找到两个相同的节点。
方法1:正常来说可能需要从一个链表list1中取出一个节点,将其与list2中的每一个节点进行比较。再去list1的下一个节点,进行比较。直到找到相同节点或遍历完全。时间复杂度O(N*N)。
方法2:计算出两个链表的长度,让较长的链表走到与较短链表的头节点的相同位置处。此时让两个节点同时走动,如果两个节点有相同的时候,那么两个链表相交。否则不相交。
在这里插入图片描述
如上图所示:第一个链表要比第二个链表长,便让head1从val=2的节点运动到val=4的节点。这样两个相同长度的链表便可以很轻松的找到相交的节点。只需要同时运动即可。

二、代码分析

1、链表长度
int ListLenth(ListNode* head)
{
    int n=0;
    while(head)//遍历链表求长度
    {
        n++;
        head=head->next;
    }
    return n;
}

链表的长度一开始并不知道,所以要进行计算来判断哪个链表长度较大。让较大的链表进行移动,并且移动多少距离也需要计算。上面的函数便是求链表长度的函数。

2、距离移动
    int lenth1=ListLenth(headA);//链表1长度
    int lenth2=ListLenth(headB);//链表2长度
    int ans=abs(lenth1-lenth2);//长度差

利用ListLenth函数分别计算出链表长度lenth1和lenth2。
ans是两个链表的长度差,保证为整数。也是较长链表要先走的距离。

	ListNode* headlong=headA;//较长链表
    ListNode* headshort=headB;//较短链表
    if(lenth1<lenth2)
    {
        headlong=headB;
        headshort=headA;
    }
    while(ans--)//移动较长链表
      headlong=headlong->next;

在开始时假定headA是较长的链表,headB是较短的链表。如果headB较长的话,只需要交换一下即可。
接着让headlong走ans的距离,使得剩余链表长度相同。

3、找出相交节点
	while(headlong&&headshort)
    {
        if(headlong==headshort)//判断是否相交
            return headlong;
        headlong=headlong->next;
        headshort=headshort->next;
    }
    return NULL;

最后循环遍历即可,找到相同的节点直接返回;如果没有相交,while循环中就不会返回,在结束后返回NULL即可。

三、完整代码

typedef struct ListNode ListNode;
int ListLenth(ListNode* head)//计算链表长度
{
    int n=0;
    while(head)//遍历链表求长度
    {
        n++;
        head=head->next;
    }
    return n;
}

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    int lenth1=ListLenth(headA);//链表1长度
    int lenth2=ListLenth(headB);//链表2长度
    int ans=abs(lenth1-lenth2);//长度差
    ListNode* headlong=headA;//较长链表
    ListNode* headshort=headB;//较短链表
    if(lenth1<lenth2)
    {
        headlong=headB;
        headshort=headA;
    }
    while(ans--)//移动较长链表
      headlong=headlong->next;
    while(headlong&&headshort)
    {
        if(headlong==headshort)//判断是否相交
            return headlong;
        headlong=headlong->next;
        headshort=headshort->next;
    }
    return NULL;
}
  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值