链表—两个链表的相交问题

本文探讨了如何判断两个链表是否相交并找到它们的交点。针对链表不带环的情况,使用快慢指针可以有效解决。如果链表可能带环,则需要分别考虑环内外的交点情况,并分析了各种环形结构下的相交条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)

2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】

1.分析:在已知链表不带环时,如果两个链表的尾部相同则相交,用快慢指针求交点。

ListNode* GetMeetNode(ListNode* list1,ListNode* list2)//判断相交点
{
   ListNode* cur1 = list1;
   ListNode* cur2 = list2;
   int len1 = 0;
   int len2 = 0;
   while(cur1)
   {
       len1++;
       cur1 = cur1->next;
    }
    while(cur2)
   {
       len2++;
       cur2 = cur2->next;
    }
    ListNode* longlist = list1;
    ListNode* shortlist = list2;
    if(len1 < len2)
    {
         longlist = list2;
         shortlist = list1;
     }
     int gap = abs(len1-len2);
     while(gap--)
     {
         longlist = longlist->next;
     }
     while(longlist)
     {
        if(longlist == shortlist)
        {
             return longlist;
        }
        longlist = longlist->next;
        shortlist = shortlist->next;
     }
     return NULL;
}

2.分析:判断L1和L2是否带环

           a.L1和L2都不带环,求链表的尾是否带环,求交点

           b.L1带环,L2不带环或L1不带环,L2带环。则L1和L2一定不相交

           c.L1和L2都带环

           1)入口点在环外—>交点+入口点

           2)入口点在环内—>两个点即是交点又是入口点

           3)带环不相交



ListNode* Istersect(ListNode* plist1, ListNode* plist2)//判断链表是否相交升级版  
{  
    //先判断是否为空  
    if ((plist1 == NULL) || (plist2 == NULL))  
    {  
        return NULL;  
    }  
    ListNode* enter1 = EnterNode(plist1);  
    ListNode* enter2 = EnterNode(plist2);  
    //1.若两个链表都无环,则直接用题目二的函数解决  
    if ((enter1 == NULL) && (enter2 == NULL))  
    {  
        return IsListIntersect(plist1, plist2);  
    }  
        //2.若一个有环,一个无环,则不想交,返回NULL  
       else if ((enter1 == NULL) && (enter2 != NULL) || (enter1 != NULL) && (enter2 == NULL))  
    {  
        return NULL;  
    }  
    //3.1  若入口点相同都在尾巴,去掉环,转化成无环相交问题  
    else if (enter1 == enter2)  
    {  
        enter1->next = NULL;  
        enter2->next = NULL;  
        return IsListIntersect(plist1, plist2);  
    }  
    //3.2 同环,两个入口点  一个入口点开始遍历一圈,看环上是否有另一个入口点    
        // 找到则返回plist1的入口点    
    else  
    {  
        ListNode* tmp = enter1->next;  
        while (tmp != enter1)  
        {  
            if (tmp == enter2)  
            {  
                return enter1;  
            }  
            tmp = tmp->next;  
        }  
        return NULL;  
    }  
}  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值