1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
1.分析:在已知链表不带环时,如果两个链表的尾部相同则相交,用快慢指针求交点。
ListNode* GetMeetNode(ListNode* list1,ListNode* list2)//判断相交点
{
ListNode* cur1 = list1;
ListNode* cur2 = list2;
int len1 = 0;
int len2 = 0;
while(cur1)
{
len1++;
cur1 = cur1->next;
}
while(cur2)
{
len2++;
cur2 = cur2->next;
}
ListNode* longlist = list1;
ListNode* shortlist = list2;
if(len1 < len2)
{
longlist = list2;
shortlist = list1;
}
int gap = abs(len1-len2);
while(gap--)
{
longlist = longlist->next;
}
while(longlist)
{
if(longlist == shortlist)
{
return longlist;
}
longlist = longlist->next;
shortlist = shortlist->next;
}
return NULL;
}
2.分析:判断L1和L2是否带环
a.L1和L2都不带环,求链表的尾是否带环,求交点
b.L1带环,L2不带环或L1不带环,L2带环。则L1和L2一定不相交
c.L1和L2都带环
1)入口点在环外—>交点+入口点
2)入口点在环内—>两个点即是交点又是入口点
3)带环不相交
ListNode* Istersect(ListNode* plist1, ListNode* plist2)//判断链表是否相交升级版
{
//先判断是否为空
if ((plist1 == NULL) || (plist2 == NULL))
{
return NULL;
}
ListNode* enter1 = EnterNode(plist1);
ListNode* enter2 = EnterNode(plist2);
//1.若两个链表都无环,则直接用题目二的函数解决
if ((enter1 == NULL) && (enter2 == NULL))
{
return IsListIntersect(plist1, plist2);
}
//2.若一个有环,一个无环,则不想交,返回NULL
else if ((enter1 == NULL) && (enter2 != NULL) || (enter1 != NULL) && (enter2 == NULL))
{
return NULL;
}
//3.1 若入口点相同都在尾巴,去掉环,转化成无环相交问题
else if (enter1 == enter2)
{
enter1->next = NULL;
enter2->next = NULL;
return IsListIntersect(plist1, plist2);
}
//3.2 同环,两个入口点 一个入口点开始遍历一圈,看环上是否有另一个入口点
// 找到则返回plist1的入口点
else
{
ListNode* tmp = enter1->next;
while (tmp != enter1)
{
if (tmp == enter2)
{
return enter1;
}
tmp = tmp->next;
}
return NULL;
}
}