33、两个链表的第一个公共结点

题目:

输入两个链表,找出它们的第一个公共结点。

解法:

提供两种解法,都为o(m+n)的时间复杂度。

前提:因为为普通链表,若两个链表有交点,从该交点开始,后面的节点都是公共的。

即有交点的话,两条链表形成Y形, 而不是X形。

(一)

假设链表1为a-b-c-d-e-NULL, 链表2为f-g-e-NULL.分别遍历两个新的组合遍历

(链表1+链表2 : a-b - c -   d  - e - NULL- f - g - e - NULL) 

(链表2+链表1 : f- g - e -NULL-a-    b   - c - d - e - NULL)

我们可以发现,第一个相同位置的交点为e,即为 第一个公共交点。

代码如下:

但是注意在(node1==NULL)?这个判断中,不能改为(node1->next==NULL)?会导致在无交点情况死循环,无法结束。

假设:链表1:abcde 链表2:fg  即该写法遍历的方式为

(abcdefg  fg  fg....)

(fgabcde  abcde  abcde....)

    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL || pHead2 ==NULL)
            return NULL;
        ListNode* node1 = pHead1;
        ListNode* node2 = pHead2;
        while(node1!=node2)
        {  //不能改为(node1->next==NULL)?,否则在没交点情况下会陷入死循环
            node1 =  (node1==NULL)? pHead2:node1->next; //链表1 结束后 转至链表2
            node2 =  (node2==NULL)? pHead1:node2->next; //链表2 结束后 转至链表1
        }
        return node1;
    }

(二)

先各自遍历两个链表得到两个链表长度len1和len2. 让长的链表从头开始先前移abs(len2-len1)

然后一起移动两个节点,比较是否相同,若有交点,则返回第一个交点,若无则最后在NULL处汇集。

代码如下:

    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL||pHead2==NULL)
            return NULL;
        int len1=1;
        int len2=1;
        ListNode* node1 =pHead1;
        ListNode* node2 = pHead2;
        while(node1->next!=NULL)//获取长度
        {
            len1++;
            node1=node1->next;
        }
        while(node2->next!=NULL)
        {
            len2++;
            node2=node2->next;
        }
        node1 = pHead1;
        node2 = pHead2;
        if(len1>len2)//链表1长
        {
            for(int i =0;i<len1-len2;i++)
                node1=node1->next;
            while(node1!=node2)
            {
                node1=node1->next;
                node2=node2->next;
            }
        }
        else//链表2长
        {
            for(int i =0;i<len2-len1;i++)
                node2=node2->next;
            while(node1!=node2)
            {
                node1=node1->next;
                node2=node2->next;
            }
        }
        return node1;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值