二维码
怎样判断两个链表相交并找到第一个相交点(微软数据结构面试题) - 数据结构 - 机器学习 #daohang ul li t,.reed .riqi,a.shangg,a.xiatt,a.shangg:hover,a.xiatt:hover,a.shang,a.xiat,a.shang:hover,a.xiat:hover,.reed-pinglun-anniu,span.now-page,#daohangs-around,#caidan-tubiao,#daohangs,#daohangs li,#btnPost{background-color:#D10B04;} .dinglanyou1 h3{border-bottom:3px solid #D10B04;} #dibuer{border-top:2px solid #D10B04;}.cebianlan .rongqi h3{border-bottom:1px solid #D10B04;} #edtSearch{border:1px solid #D10B04;} #daohang .zuo ul li{border-right:1px solid #;} #daohang ul li t a{border-top:1px solid #;border-right:1px solid #D10B04;} #daohang ul li t a:hover{border-right:1px solid #;} #daohang .you ul li a:hover,#daohang .zuo ul li a:hover,.reed-pinglun-anniu:hover{background-color:#;} a:hover,.reed h6 a:hover,#dibuer a:hover,.reed .riqiding,.cebianlan .rongqi li a:hover,#pinglun-liebiao ul.fubens li.depth-1 dl dd span.shu a,#pinglun-liebiao ul.fubens li.depth-1 dl dd span.huifuliuyan a:hover,.reed-biaoti h6 span{color:#D10B04;} .reed .kan a{color:#0A0AF5;}.reed .kan a:hover{color:#D10101;} @media screen and (max-width:1492px){a.shang,a.xiat{background:none;} a.xiat:hover,a.shang:hover{background-color:#f9f9f9;background-image:none;text-decoration:none;}} var _hmt = _hmt || [];(function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?b19db5ba3b437a9e8698d2bc8fc64334"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s);})(); var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?b19db5ba3b437a9e8698d2bc8fc64334"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?2d748c9763cfc72fb7d1ccab29f0770d"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?f6d451f3f1be23f3abf240c64c469c1b"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();

当前位置:首页 » 面试笔试 » 正文

(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646201", container: s }); })();
(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646162", container: s }); })();

怎样判断两个链表相交并找到第一个相交点(微软数据结构面试题)

1517 人参与  2018年08月18日 08:58  分类 : 面试笔试  评论

怎样判断两个链表相交并找到第一个相交点(微软数据结构面试题) - 数据结构 - 机器学习

1、给出两个单向链表的头指针pHead1和pHead2,判断这两个链表是否相交。假设两个链表均不带环。

如果两个链表相交于某一节点,那么在这个相交节点之后的所有节点都是两个链表所共有的。也就是说,如果两个链表相交,那么最后一个节点肯定是共有的。先遍历第一个链表,记住最后一个节点,然后遍历第二个链表,到最后一个节点时和第一个链表的最后一个节点做比较,如果相同,则相交,否则不相交。时间复杂度为O(len1+len2),因为只需要一个额外指针保存最后一个节点地址,空间复杂度为O(1)。

2、给出一个单向链表的头指针pHead,判断链表中是否有环。

链表中有环,其实也就是自相交。我们用两个指针pslow和pfast从头开始遍历链表,pslow每次前进一个节点,pfast每次前进两个结点,若存在环,则pslow和pfast肯定会在环中相遇,若不存在,则pslow和pfast能正常到达最后一个节点(实际上是到达NULL)。
代码如下:

// 判断链表中是否有环
bool IsExitLoop(LinkList *head)
{
    LinkList *pslow = head;
    LinkList *pfast = head;
    while(pfast != NULL && pfast->next != NULL)
    {
        pslow = pslow->next;        // 每次前进一步
        pfast = pfast->next->next;  // 每次前进二步
        if(pslow == pfast)          // 两个指针相遇,说明存在环
            return true;
    }
    return false;    // 没有环
}

3、给出两个单向链表的头指针pHead1和pHead2,判断这两个链表是否相交,若相交返回第一个相交的节点。假设两个链表均不带环。
方法一:
    判断两个链表中是否存在地址一致的节点,就可以知道是否相交了。可以对第一个链表的节点地址进行hash排序,建立hash表,然后针对第二个链表的每个节点的地址查询hash表,如果它在hash表中出现,则说明两个链表有共同的结点。这个方法的时间复杂度为:O(max(len1+len2);但同时还得增加O(len1)的存储空间存储哈希表。这样减少了时间复杂度,增加了存储空间。
    以链表节点地址为值,遍历第一个链表,使用Hash保存所有节点地址值,结束条件为到最后一个节点(无环)或Hash中该地址值已经存在(有环)。

方法二:
    对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。
    对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点相同,若不相同,则不相交,程序结束。
    若相交,两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点,此时两个链表当前节点到第一个相交节点的距离就相等了,比较下一个节点是不是相同,如果相同就返回该节点(即相交节点),若不相同,两个链表都同步向后走一步,继续比较。

方法三:

    由于两个链表都没有环,我们可以把第二个链表接在第一个链表的后面,如果得到的链表有环,则说明这两个链表相交。否则,这两个链表不相交。这样我们就把问题转化为判断一个链表是否有环了。最后,当然可别忘记恢复原来的状态,去掉从第一个链表到第二个链表表头的指向。
4、给出一个单向链表的头指针pHead,判断链表中是否有环,若存在,则求出进入环中的第一个节点。
   

    首先使用第2个题目中的快、慢指针来判断链表是否存在环,若不存在结束。
    若链表中存在环,我们从链表头、与两个指针的相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇的第一个点为环的入口点。

代码如下:

// 找到环的第一个入口点
LinkList* FindLoopPort(LinkList *head)
{
    LinkList *pslow = head;
    LinkList *pfast = head;
    while(pfast != NULL && pfast->next != NULL)
    {
        pslow = pslow->next;        // 每次前进一步
        pfast = pfast->next->next;  // 每次前进二步
        if(pslow == pfast)          // 两个指针相遇,说明存在环
            break;
    }
    if(pfast == NULL || pfast->next == NULL)    // 不存在环
        return NULL;
    pslow = head;
    while(pslow != pfast)
    {
        pslow = pslow->next;        // 每次前进一步
        pfast = pfast->next;        // 每次前进一步
    }
    return pslow;       // 返回环的入口点
}

    分析:当pfast若与pslow相遇时,pslow肯定没有走遍历完链表,而pfast已经在环内循环了n圈(1<=n)。假设pslow走了s步,则pfast走了2s步(pfast步数还等于s 加上在环上多转的n圈),设环长为r,则:    

    2s = s + nr    s= nr
    设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。   

    a + x = nr  则: 

    a + x = (n – 1)r +r = (n-1)r + L - a   

    a = (n-1)r + (L – a – x)
    (L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。
    小结:链表是数据结构中最基本的,也是面试中常考的,与链表相关的题目也变化多端,只要基础扎实,多积累一些处理类似问题的技巧,面试时便能应对自如。

    单链表的的归并排序,同样需要找到链表的中间节点,可以使用前面的这个快、慢指针的方法。

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode , *LinkList;
// 对两个有序的链表进行递归的归并
LinkList MergeList_recursive(LinkList head1 , LinkList head2)
{
    LinkList result;
    if(head1 == NULL)
        return head2;
    if(head2 == NULL)
        return head1;
    if(head1->data < head2->data)
    {
        result = head1;
        result->next = MergeList_recursive(head1->next , head2);
    }
    else
    {
        result = head2;
        result->next = MergeList_recursive(head1 , head2->next);
    }
    return result;
}
// 对两个有序的链表进行非递归的归并
LinkList MergeList(LinkList head1 , LinkList head2)
{
    LinkList head , result = NULL;
    if(head1 == NULL)
        return head2;
    if(head2 == NULL)
        return head1;
    while(head1 && head2)
    {
        if(head1->data < head2->data)
        {
            if(result == NULL)
            {
                head = result = head1;
                head1 = head1->next;
            }
            else
            {
                result->next = head1;
                result = head1;
                head1 = head1->next;
            }
        }
        else
        {
            if(result == NULL)
            {
                head = result = head2;
                head2 = head2->next;
            }
            else
            {
                result->next = head2;
                result = head2;
                head2 = head2->next;
            }
        }
    }
    if(head1)
        result->next = head1;
    if(head2)
        result->next = head2;
    return head;
}
// 归并排序,参数为要排序的链表的头结点,函数返回值为排序后的链表的头结点
LinkList MergeSort(LinkList head)
{
    if(head == NULL)
        return NULL;
    LinkList r_head , slow , fast;
    r_head = slow = fast = head;
// 找链表中间节点的两种方法
/*
    while(fast->next != NULL)
    {
        if(fast->next->next != NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        else
            fast = fast->next;
    }*/
    while(fast->next != NULL && fast->next->next != NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    if(slow->next == NULL)    // 链表中只有一个节点
        return r_head;
    fast = slow->next;
    slow->next = NULL;
    slow = head;
// 函数MergeList是对两个有序链表进行归并,返回值是归并后的链表的头结点
//r_head = MergeList_recursive(MergeSort(slow) , MergeSort(fast));
    r_head = MergeList(MergeSort(slow) , MergeSort(fast));
    return r_head;
}

来源:我是码农,转载请保留出处和链接!

本文链接:http://www.54manong.com/?id=7

(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646208", container: s }); })();
(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646147", container: s }); })();
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdPic":"","bdStyle":"0","bdSize":"16"},"share":{},"image":{"viewList":["qzone","tsina","tqq","renren","weixin"],"viewText":"分享到:","viewSize":"16"},"selectShare":{"bdContainerClass":null,"bdSelectMiniList":["qzone","tsina","tqq","renren","weixin"]}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
数据结构习题解析  

微信号:qq444848023    QQ号:444848023

加入【我是码农】QQ群:864689844(加群验证:我是码农)

<< 上一篇 下一篇 >>
(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646186", container: s }); })();
(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646175", container: s }); })();
搜索

网站分类

标签列表

最近发表

    (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https'){ bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else{ bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();

全站首页 | 数据结构 | 区块链| 大数据 | 机器学习 | 物联网和云计算 | 面试笔试

var cnzz_protocol = (("https:" == document.location.protocol) ? "https://" : "http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1276413723'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s23.cnzz.com/z_stat.php%3Fid%3D1276413723%26show%3Dpic1' type='text/javascript'%3E%3C/script%3E"));本站资源大部分来自互联网,版权归原作者所有!

jQuery(document).ready(function($){ /* prepend menu icon */ $('#daohangs-around').prepend('
'); /* toggle nav */ $("#caidan-tubiao").on("click", function(){ $("#daohangs").slideToggle(); $(this).toggleClass("active"); }); });

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

©著作权归作者所有:来自ZhiKuGroup博客作者没文化的原创作品,如需转载,请注明出处,否则将追究法律责任 来源:ZhiKuGroup博客,欢迎分享。

评论专区
  • 昵 称必填
  • 邮 箱选填
  • 网 址选填
◎已有 0 人评论
搜索
作者介绍
30天热门
×
×
关闭广告
关闭广告
本站会员尊享VIP特权,现在就加入我们吧!登录注册×
»
会员登录
新用户注册
×
会员注册
已有账号登录
×