您的位置:首页 > 职场人生

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

2015-07-06 22:24 651 查看
本题目选自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;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息