两种方法解决相交链表(两种双指针法and成环法)

题目:

在这里插入图片描述

朴素双指针法:

//典型双指针问题,先根据两个链表的长度把两个指针所指位置平齐,然后再同时双指针扫描,一旦相等则为交点。
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int L1 = getLen(headA);
        int L2 = getLen(headB);
        //双指针平齐
        if(L1>L2){
            int gap = L1-L2;
            for(int i=1;i<=gap;i++)
                headA = headA->next;
        }
        else{
            int gap = L2-L1;
            for(int i = 1;i<=gap;i++)
                headB = headB->next;
        }
        //双指针移动:
        while(headA!=headB){
            headA = headA->next;
            headB = headB->next;
        }
    return headB;
    }
private:
    int getLen(ListNode* head){
        if(head)
            return getLen(head->next)+1;
        else
            return 0;
    }
};

效率尚可
在这里插入图片描述

成环法(时间复杂度高,但实用性强):

代码


class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(!headA||!headB)
            return nullptr;
        ListNode* t1 = headA;
        ListNode* t2 = headB;
        while(t1!=t2){
            //如果t1或t2到null了就直接等于头指针(相当于循环)
            //这里判断t1和t2而不是t->next是因为需要经过null状态。
            //要是跳过了null状态,如果两者没有相交则无限循环。
            t1 = t1?t1->next:headA;
            t2 = t2?t2->next:headB;
        }
        return t1;
    }
};

原理解析:

这里图解是跳过了null状态,但是实际不能跳过,加入null状态,也就是在最后多加一个结点即可。
在这里插入图片描述
没错时间复杂度确实是O(n^2)(别看代码简短)
在这里插入图片描述

进阶双指针法(利用同时遍历长度相等原理)

代码

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(!headA||!headB)
            return nullptr;
        ListNode* t1 = headA;
        ListNode* t2 = headB;
        while(t1!=t2){
            //只需要在成环法的基础上改为遍历到另一个链表
            t1 = t1?t1->next:headB;
            t2 = t2?t2->next:headA;
        }
        return t1;
    }
};

详解
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值