链表相交问题

1、判断两个链表是否有交点,假设不带环

问题描述:如果两个链表相交,则返回交点,如果不相交,则返回NULL
解题思路一:(1)先求出两个链表的长度l1,l2
(2)求出长度的差值k
(3)让较长的链表先走k步,然后两个链表一起向后移动,如果有相等的节点,则说明链表相交
当然还要考虑链表为空的情况,如果至少一个链表为空,则直接返回NULL

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode
     */
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // write your code here
        ListNode* h1=headA;
        ListNode* h2=headB;
        int L1,L2,k;
        if(headA==NULL || headB==NULL)
        {
            return NULL;
        }
        while(h1)
        {
            L1++;
            h1=h1->next;
        }

        while(h2)
        {
            L2++;
            h2=h2->next;
        }
        if(L1<L2)
        {
            h1=headB;
            h2=headA;
            L1^=L2;
            L2^=L1;
            L1^=L2;
        }
        else
        {
            h1=headA;
            h2=headB;
        }
        k=L1-L2;
        while(k>0)
        {
            h1=h1->next;
            --k;
        }

        while(h1!=h2)
        {
            h1=h1->next;
            h2=h2->next;
        }
        return h1;
    }
};

解题思路二:如果有解决过链表的带环问题的话,可以将这道题转化成链表的带环问题,也就是先遍历其中一个链表,到第一个链表的尾部之后,让该链表指向另一个链表的头部,由此可以将这个问题转化为链表环的入口点的问题。

2、判断两个链表是否有交点,假设链表带环

问题描述:如果两个链表相交,则返回交点,如果不相交,则返回NULL
解题思路:
这里写图片描述

pNode IsCrossWithCircle(pNode pHead1, pNode pHead2)//判断两个链表是否相交,若相交,求交点(假设链表可能带环)
{
    pNode p1 = HasCircle(pHead1);//求链表1的相遇节点
    pNode p2 = HasCircle(pHead2);//求链表2的相遇节点
    pNode p11 = p1;
    pNode pret1 = NULL;
    pNode pret2= NULL;
    pNode pret3 = NULL;
    pNode NewMeet = NULL;
    int iret = 0;
    if ((NULL == pHead1 || NULL == pHead2) || (p1 && NULL == p2) || (p2 && NULL == p1))//若任意一个链表为空或者只有一个链表带环,则不可能相交
    {
        return NULL;
    }

    if (NULL== p1 && NULL== p2)//两个链表都不带环
    {
        iret = IsCross(pHead1, pHead2);//不相交
        if (0 == iret)
            return NULL;
        else//相交
        {
            pret1 = GetCrossNode(pHead1, pHead2);
            return pret1;//返回交点
        }       
    }
    if (p1 && p2)//两个都带环
    {
        pret2 = GetEnterNode(pHead1, p1);//求出pHead1的入口点
        pret2->next = pHead1;//指向自己
        NewMeet = HasCircle(pHead2);//求链表2的相遇节点
        pret3 = GetEnterNode(pHead2, NewMeet);//求出链表2的入口点
        return pret3;
    }
    else
        return NULL;//不相交
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值