1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
来判断两个链表是否相交
思路:两个链表相交最后一个节点必定相等,所以让两个链表遍历到最后一个结点,判断是否相等
int IsListCross(ListNode* p1, ListNode* p2)//判断两个链表是否相交
{
assert(p1);
assert(p2);
while (p1->next)
{
p1 = p1->next;
}
while (p2->next)
{
p2 = p2->next;
}
if (p1 == p2)
return 1;
else
return 0;
}
求交点
思路:计算两个链表长度,让长的先走上两个链表的差,短链表从头开始,当两个相等时找到结点
ListNode* GetCrossNode(ListNode* p1, ListNode* p2)//求交点
{
assert(p1);
assert(p2);
ListNode* Cur1 = p1;
ListNode* Cur2 = p2;
int len1 = 0;
int len2 = 0;
int sub = 0;
while (Cur1)
{
Cur1 = Cur1->next;
len1++;
}
while (Cur2)
{
Cur2 = Cur2->next;
len2++;
}
sub = len1 - len2;
Cur1 = p1;
Cur2 = p2;
if (sub > 0)
{
while (sub--)
p1 = p1->next;
}
else if(sub < 0)
{
while (sub++)
p2 = p2->next;
}
while (p1 && p2)
{
p1 = p2->next;
p2 = p2->next;
if (p1 == p2)
return p1;
}
return NULL;
}
2.判断两个链表是否相交,若相交,求交点。(假设链表带环)
思路:判断两个链表是否为空,为空则不可能相交。判断两个链表是否带环,若都不带环则按照不带环的方式求,若有一个带环一个不带环这种情况不可能相交,若两个都带环求处环的相遇点,遍历环如果遍历一圈都没有与另外一个链表的相遇点相等则表明这两个链表不相交。
int IsListCrossWithCircle(ListNode* p1, ListNode* p2)//判断两个链表是否相交(假设链表带环)
{
if (p1 == NULL || p2 == NULL)
return 0;
if (0 == HasListCircle(p1) && 0 == HasListCircle(p2))
{
ListNode* pTailNode1 = p1;
ListNode* pTailNode2 = p2;
while (pTailNode1->next)
pTailNode1 = pTailNode1->next;
while (pTailNode2->next)
pTailNode2 = pTailNode2->next;
if (pTailNode1 = pTailNode2)
return 1;
}
else if (HasListCircle(p1) && HasListCircle(p2))
{
ListNode* pMeetNode1 = GetMeetNode(p1);
ListNode* pMeetNode2 = GetMeetNode(p2);
ListNode* pCur = pMeetNode1;
while (pCur->next != pMeetNode1)
{
if (pCur == pMeetNode2)
return 2;
pCur = pCur->next;
}
if (pCur == pMeetNode2)
{
return 2;
}
}
return 0;
}
关于环的函数,在上一篇博中有,可以借鉴参考。