链表双指针总结(2)- LeetCode - 每日一题 - Day2

链表的两大劣势就是无法快速访问某个元素和涉及链表的长度问题,但是有这么几个题就是专门针对这方面出的,例如:

两个单链表相交的起始结点

在这里插入图片描述

  • 法一:

法一思路:让两个链表pA和pB分别遍历往后走,谁先到了尾谁就赋值为另一条链表的头,再继续一起走,当他们相交的时候就是目标结点

刚开始看这段话大家应该看不明白,可以这么理解:在相交之前,它们走过的路程其实是相同的,因为两个指针速度相同,想要相遇那么走过的路程肯定会相等,否则怎么可能会撞到一起?
在这里插入图片描述

**如下图,P2先碰到了NULL,那么赋值为HeadA,走一遍HeadA的路程,当P1也到了NULL时,就赋值为HeadB,走HeadB的路程
在这里插入图片描述在这里插入图片描述

到Head的步骤是赋值,不需要走。

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
    struct ListNode* pA = headA;
    struct ListNode* pB = headB;
    while (pA != pB)
    {
        pA = pA == NULL ? pA = headB : pA->next;
        pB = pB == NULL ? pB = headA : pB->next;
    }
    return pA;
}
  • 法二:

法二思路:如果这两个单链表pA,pB相交,那它们一定会有相同的尾结点,而且它们的长度相差多少未知。那么可以先让pA,pB分别遍历一遍链表,记录其长度,然后得到长度的差值gap,再让长的链表(假设为pA)先走gap步,那么它们会处于同一出发点,当pA和pB相等的时候就是那个目标结点
在这里插入图片描述在这里插入图片描述

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    //遍历A计数
    struct ListNode* tmp = headA;
    int count = 1;
    while(tmp)
    {
        tmp = tmp->next;
        count++;
    }
    //遍历B计数
    struct ListNode* scendtmp = headB;
    int scendcount = 1;
    while(scendtmp)
    {
        scendtmp = scendtmp->next;
        scendcount++;
    }
    //没有公共尾结点说明不相交
    if(scendtmp != tmp)
    {
        return NULL;
    }
    //假设其中一个为长,让它先走gap步
    struct ListNode* longlist = headA;
    struct ListNode* shortlist = headB;
    if(count < scendcount)
    {
        longlist = headB;
        shortlist = headA;
    } 
    int gap = abs(count - scendcount);
    while(gap--)
    {
        longlist = longlist->next;
    }
    //若相等就说明找到了目标点
    while(longlist != shortlist)
    {
        longlist = longlist->next;
        shortlist = shortlist->next;
    }
    return shortlist;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值