每日一题---OJ题: 相交链表

片头

嗨! 小伙伴们,大家好! 今天我们来一起学习这道OJ题---相交链表,准备好了吗? Ready Go!  !  !

emmm,看这道题好像不怎么难,我们一起画图分析分析 

上图中,A链表有5个结点,分别为 a1,a2,c1,c2,c3 ; B链表有6个结点,分别为 b1,b2,b3,c1,c2,c3 ; A链表和B链表在c1结点相交

怎么做这道题呢? 第一种思路就是暴力穷举,也是一种比较容易想到的办法

思路一: 让A链表的每一个结点依次跟B链表中的结点进行比较,如果有相等就是相交,第一个相等就是交点。

代码如下:

 typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
        ListNode* pA = headA;   //定义一个指向A链表的指针
        ListNode* pB = headB;   //定义一个指向B链表的指针

        //让A链表的每一个结点依次和B链表中的结点进行比较
        for(pA = headA; pA != NULL; pA = pA->next){
            for(pB = headB; pB != NULL; pB = pB->next){
                if(pA == pB){   //如果有相等就是相交
                    return pA;  //第一个相等就是交点
                }
            }
        }
        return NULL;            //如果没有相交,返回NULL
} 

我们把代码放到leetcode上面,显示通过

那还没有另外一种思路呢? 肯定有,且听我慢慢道来~

思路二:  1. 判断是否相交先找尾结点,尾结点的地址相同就相交; 2.找交点 长的链表先走长度差,再同时走找交点(第一个地址相同的就是交点)。

判断是否相交的代码如下:(因为后面我们需要知道长度差,因此在寻找尾结点的同时就计算链表的长度,效率更高)

        ListNode* pA = headA;       //定义pA指针,指向A链表的头结点
        ListNode* pB = headB;       //定义pB指针,指向B链表的头结点

        int lenA = 0;               //A链表的长度
        while(pA->next != NULL)     //寻找A链表的尾结点
        {
            pA = pA->next;          //如果不是尾结点,pA往后走一步
            lenA++;                 //lenA的长度自增一次
        }
        lenA = lenA+1;              //别忘了加上尾结点

        int lenB = 0;                //B链表的长度
        while(pB->next != NULL)      //寻找B链表的尾结点
        {
            pB = pB->next;           //如果不是尾结点,pB往后走一步
            lenB++;                  //lenA的长度自增一次
        }
        lenB = lenB+1;               //别忘了加上尾结点

        if(pA != pB){                //如果尾结点不相同,说明两个链表不会相交
            return NULL;             //返回NULL
        }

接下来就是尾结点相同,说明两个链表相交,我们一起来找交点

部分代码如下: 

 //尾结点相同,说明两个链表相交,我们一起来找交点
        int gap = abs(lenA-lenB);   //abs()函数用来求绝对值

        //假设A链表的长度比B链表短
        //用变量shortList定义A链表,变量longList定义B链表
        ListNode* shortList = headA;
        ListNode* longList = headB;

        //如果A链表的长度比B链表长
        if(lenA > lenB)
        {
            longList = headA;  //变量longList定义A链表
            shortList = headB;//用变量shortList定义B链表,
        }

        //长的链表先走长度差
        while(gap--){
            longList = longList->next;
        }
        //再同时走找交点
        while(longList != shortList){
            longList = longList->next;
            shortList = shortList->next;
        }
        //找到交点了,返回结点
        return longList;

OK,这道题被我们解决了,整体代码如下:

typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
        ListNode* pA = headA;       //定义pA指针,指向A链表的头结点
        ListNode* pB = headB;       //定义pB指针,指向B链表的头结点

        int lenA = 0;               //A链表的长度
        while(pA->next != NULL)     //寻找A链表的尾结点
        {
            pA = pA->next;          //如果不是尾结点,pA往后走一步
            lenA++;                 //lenA的长度自增一次
        }
        lenA = lenA+1;              //别忘了加上尾结点

        int lenB = 0;                //B链表的长度
        while(pB->next != NULL)      //寻找B链表的尾结点
        {
            pB = pB->next;           //如果不是尾结点,pB往后走一步
            lenB++;                  //lenA的长度自增一次
        }
        lenB = lenB+1;               //别忘了加上尾结点

        if(pA != pB){                //如果尾结点不相同,说明两个链表不会相交
            return NULL;             //返回NULL
        }

        //尾结点相同,说明两个链表相交,我们一起来找交点
        int gap = abs(lenA-lenB);   //abs()函数用来求绝对值

        //假设A链表的长度比B链表短
        //用变量shortList定义A链表,变量longList定义B链表
        ListNode* shortList = headA;
        ListNode* longList = headB;

        //如果A链表的长度比B链表长
        if(lenA > lenB)
        {
            longList = headA;  //变量longList定义A链表
            shortList = headB;//用变量shortList定义B链表,
        }

        //长的链表先走长度差
        while(gap--){
            longList = longList->next;
        }
        //再同时走找交点
        while(longList != shortList){
            longList = longList->next;
            shortList = shortList->next;
        }
        //找到交点了,返回结点
        return longList;
} 

哈哈哈,代码量看似很多,但是里面的逻辑一点也不复杂,只要认真分析,一定能克服难关!

片尾

今天我们学习了一道OJ题: 相交链表,里面运用到了计算链表的长度,查找链表的尾结点以及比较两个链表的结点等相关知识,希望看完这篇文章能对友友们有所帮助 !    !    !

点赞收藏加关注 !   !   !

谢谢大家 !   !   !

 

 

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值