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; }
时间: 2024-10-10 22:18:18