判断两个不带环链表是否相交?若相交,求入口点。

这里写图片描述

通常情况下,不带环的两个链表相交如上图所示。
方法一:<1>先判断链表是否相交
①若相交,那么两个链表的尾节点必然相同。则可以遍历两个链表,判断其尾节点。
②若不相交,则尾节点必然不相同。
<2>若相交,求其入口点
①通过遍历两个链表可以得到其长度(假设为len1和len2),通过比较len(len=abs(len1-len2)),让长的链表先走len步,然后两个链表同时走,当他们遇到第一个相等的节点的时候,即为其入口点。

这里写图片描述

//判断两链表是否相交
typedef struct ListNode 
{
    int _data;
    ListNode *_next;
}Node;

bool IsCrossList(Node *head1 , Node *head2)   //判断两个链表是否相交
{
    if (head1 == NULL || head2 == NULL || head1->_next == NULL || head2->_next == NULL)
    {
        return false;
    }

    while (head1)
    {
        head1 = head1->_next;   
    }

    while (head2)
    {
        head2 = head2->_next;   
    }

    return head1 == head2 ? true : false;
}
//判断链表的入口点
Node *CrossNode(Node *head1,Node *head2)
{
    Node *cur1 = head1;
    Node *cur2 = head2;

    size_t len = 0;
    size_t len1 = 0;
    size_t len2 = 0;

    while (cur1)
    {
        cur1 = cur1->_next;
        ++len1;
    }
    while(cur2)
    {
        cur2 = cur2->_next;
        ++len2;
    }

    len = abs(len1 - len2);

    if (len1>len2)
    {
        for (size_t i=0;i<len;i++)
        {
            head1 = head1->_next;
        }       
    } 
    else
    {
        for (size_t i=0;i<len;i++)
        {
            head2 = head2->_next;
        }
    }

    while (head1 != head2)
    {
        head2 = head2->_next;
        head1 = head1->_next;
    }
        return head1;   
}

方法二:直接建立两个栈,把链表放入栈中,遵循先进后出原则,尾节点先出,即可判断是否相交。出栈的最后一个相同节点即为入口点。

Node *CrossNode(Node *head1,Node *head2)
{
    if (head1 == NULL || head2 == NULL)
    {
        return NULL;
    }

    stack<Node*> s1;   
    stack<Node*> s2;    //创建两个栈

    Node *cur1 = NULL;
    Node *cur2 = NULL;

    while (head1 != NULL)
    {
        cur1 = head1;
        s1.push(cur1);
        head1 = head1->_next;
    }

    while (head2 != NULL)
    {
        cur2 = head2;
        s2.push(cur2);
        head2 = head2->_next;
    }

    if (cur1 == cur2)
    {
        Node *ret = NULL;
        while(s1.top() == s2.top())
        {
            ret = s1.top();
            s1.pop();
            s2.pop();
        }
            return ret;
    }
    else
    {
        return NULL;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值