标签:
9.判断两个单链表是否相交
注意这里是判断是否相交。对于判断问题来讲,相对还是比较简单的。注意单链表并非不能有重复元素。
思路1:O(len1*len2)
把第一个链表的指针值逐项存在hashtable中,遍历第2个链表的每一项的指针值,如果能在第一个链表中找到,则必然相交。但是C++的STL模板中的hash不太会用。所以我使用了set集合,不过貌似set集合是使用遍历的方式来查找元素是否在集合中的,所以效率是比较低的,至少在O(len1*len2)级别。
bool judgeIntersectList1(Node* Head1,Node* Head2)
//判断两个单链表是否相交(Y型)
bool judgeIntersectList1(Node* Head1,Node* Head2)
{
set<Node*>s;
Node* p1=Head1;
Node* p2=Head2;
while(p1!=NULL)
{
s.insert(p1);
p1=p1->next;
}
while(p2!=NULL)
{
if(s.find(p2)!=s.end())
{
s.clear();
return true;
}
p2=p2->next;
}
s.clear();
return false;
}
思路2:O(len1+len2)
把一个链表A接在另一个链表B的末尾,如果有环,则必然相交。如何判断有环呢?从A开始遍历,如果能回到A的表头,则肯定有环。
注意,在返回结果之前,要把刚才连接上的两个链表断开,恢复原状。
bool judgeIntersectList2(Node* Head1,Node* Head2)
//判断两个单链表是否相交(Y型)
bool judgeIntersectList2(Node* Head1,Node* Head2)
{
if(Head1==NULL||Head2==NULL)
{
return false;
}
Node* p1=Head1;
Node* p2=Head2;
while(p2->next!=NULL) //先找到链表2的末尾,由p2指向
{
p2=p2->next;
}
p2->next=p1; //将链表1的表头与链表2的表尾连接
while(p1!=NULL) //遍历链表1,如果回到了链表1表头,则相交
{
if(p1->next==Head1)
{
p2->next=NULL; //恢复原状
return true;
}
p1=p1->next;
}
p2->next=NULL; //恢复原状
return false;
}
思路3:O(len1+len2)
如果两个链表的末尾元素相同(指针相同,即为同一个元素,而非值相等),则必相交。
bool judgeIntersectList3(Node* Head1,Node* Head2)
//判断两个单链表是否相交(Y型)
bool judgeIntersectList3(Node* Head1,Node* Head2)
{
if(Head1==NULL || Head2==NULL)
{
return false;
}
Node* p1=Head1;
Node* p2=Head2;
while(p1->next!=NULL) //p1与p2记录两链表的尾指针
p1=p1->next;
while(p2->next!=NULL)
p2=p2->next;
if(p1==p2)
{
return true;
}
return false;
}
标签:
原文地址:http://www.cnblogs.com/claremore/p/5922491.html