【从零单排之微软面试100题系列】07之判断两个链表是否相交

原创 2015年07月06日 22:24:11
本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。

题目描述:给出两个单向链表的头指针,判断两个链表是否相交。

 

分析思路:

如果只要判断是否相交,那么将每个链表遍历到表尾,看两个链表的表尾是不是同一个结点。因为相交的链表,最后一个结点肯定是公共的。

bool is_jointed1(Node* h1, Node* h2)
{
   if(h1 == NULL || h2 == NULL)
        return false;
    while(h1->next != NULL)
        h1 = h1->next;
     while(h2->next != NULL)
        h2 = h2->next;

     return h1 == h2;
}

此题比较简单,可再进行如下扩展:

(1)如果两个链表可能存在环,如何判断?

(2)(《剑指offer》面试题37)如何求两个链表的第一个公共结点。

对于(1),可以先判断每个链表是否存在环,分三种情况:1.都不存在环;2.只有一个存在环;3.两个都存在环。

都不存在环的情况上面已经讨论,只有一个链表存在环,说明肯定不会相交。接下来处理两个都存在环的情况。

判断存在环的代码:

Node* is_a_loop(Node* pHead)
{
    if(pHead == NULL || pHead->next ==NULL)
       return NULL;
    //定义一个快指针和慢指针,如果慢指针能够追上快指针,则存在环
    Node* p1 = pHead;
    Node* p2 = pHead->next;
    while(p2 != NULL && p2->next != NULL)
    {
       p1 = p1->next;          //一次走1步
       p2 = p2->next->next;    //一次走2步
       if( p1 == p2)
         return p1;            //返回的是环中的一个结点
    }
    return NULL;
}
假设两个链表都存在环:

bool is_jointed2(Node* h1, Node* h2)
{
    //保存两个链表中环的中的某个结点
    node* cyclic1 = is_a_loop(h1);
    node* cyclic2 = is_a_loop(h2);
    Node* p = cyclic1;
    while(1)
    {
       //在第一个环中绕一圈,看是否存在与cylic2相等的结点
       if(p == cylic2) return ture;
       //p = p->next->next;      <pre name="code" class="cpp">       p = p->next
//cylic1 = cylic1->next;
if(p == cylic1) return false;
 }
}



对于(2),可以根据书上的思路:首先分别遍历两个链表,得到链表的长度n1和n2。然后在长链表上先走|n1-n2|步,再同时在两个链表上遍历,找到第一个相同的结点。

//获取链表的长度
unsigned int GetListLength(Node* pHead)
{
     unsigned int nLength = 0;
     Node* pNode = pHead;
     while(pNode != NULL)
     {
          pNode = pNode->next;
          ++nLength; 
     }
     return nLength;
}

//找第一个公共结点

Node* FindFirstCommonNode(Node* pHead1, Node* pHead2)
{
     unsigned int nLen1 = GetListLength(pHead1);<pre name="code" class="cpp">     unsigned int nLen2 = GetListLength(pHead2);
     int nLenDif = nLen1 - nLen2;
    
     Node* pLong = pHead1;
     Node* pShort = pHead2;
     if(nLenDif < 0)
     {
          pLong = pHead2;
          pShort = pHead1;
          nLenDif = nLen2 - nLen1;
     }
     
     for(int i = 0; i < nLenDif; ++i)
          pLong = pLong->next;
     while(pLong != NULL && pShort != NULL && pLong != pShort)
     {
          pLong = pLong->next;
          pShort = pShort->next;
     }
    
     return pLong;
}






相关文章推荐

【从零单排之微软面试100题系列】01之二叉查找树与双向链表

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:把二元查找数转变成排序的双向链表 要求:输入一棵二元查找树,不能创建任何新的节点,只...

July大神微软等100题之第7题------判断两个链表相交(包含有无环),链表是否有环题目总结

今天才发现,当年考研的最后一题还有常数上更优的时间复杂度算法。。。 判断两个单链表是否相交: 我写的: 遍历Link1,O(L1) 遍历Link2,O(L2) 将长的链表指针后移|L2-L1|个长...

【从零单排之微软面试100题系列】03之求子数组的最大和

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:输入一个整形数组,数组里有正也有负。数组中连续的一个或多个整数组成一个子数组,每个子数...

【从零单排之微软面试100题系列】04之二叉树中和为某一值的路径

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:输入一课二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。 路径定...

【从零单排之微软面试100题系列】02之包含 min 函数的栈

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:设计包含 min 函数的栈 要求:定义栈的数据结构,添加一个min函数,能够得到栈的...

【从零单排之微软面试100题系列】05之查找最小的k个元素

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:输入n个整数,输出其中最小的k个(k   分析思路:(本题亦见于《剑指offe...

【从零单排之微软面试100题系列】06之根据上排数写出下排数

本题目选自July大神博客系列【微软面试100题】:july大神,该系列我主要用来记录我的学习笔记。 题目描述:根据给出的上排的十个数,在其下排填出对应的十个数,要求下排每个数都是先前上排那十个...

微软100题(7) 判断两链表是否相交

题目: 给出两个单链表的头指针h1 h2,判断两个链表是否相交 思路: 1.如果两个链表都没有环:        如果相交:则尾结点一定一样        如果不相交,尾...

微软面试100题系列---把二叉查找树转换成排序的双向链表

题目:把二叉查找树转换成排序的双向链表输入:一个二叉查找树输出:排序的双向链表;​要求:不能创建任何新的节点,只能调整指针的方向;实现:对二叉查找树进行中序遍历,对遍历的当前节点加入到链表末尾即可;加...

微软面试100题系列:一道合并链表问题的解答[第42题]

微软面试100题V0.1版第42题 合并链表解答July、网友   二零一一年一月2日------------------------------------本文参考:本人整理的微软面试100题系列V...
  • v_JULY_v
  • v_JULY_v
  • 2011年01月02日 10:02
  • 11141
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【从零单排之微软面试100题系列】07之判断两个链表是否相交
举报原因:
原因补充:

(最多只允许输入30个字)