#include<iostream>
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
//判断两个单向链表是否相交,若相交返回相交节点,不相交则返回空
ListNode* getIntersectNode(ListNode* head1, ListNode* head2)
{
ListNode* loop1 = findLoop(head1);
ListNode* loop2 = findLoop(head2);
// (1)两个无环链表的相交问题
if (loop1 == NULL && loop2 == NULL)
{
return noLoop(head1, head2);
}
// (2)一个链表有环,一个链表无环,不可能相交
else if (loop1 == NULL || loop2 == NULL)
{
return NULL;
}
// (3)两个有环链表相交问题
else
{
return bothLoop(head1, loop1, head2, loop2);
}
}
private:
//(1)判断链表是否有环,若有返回入环节点,若没有返回空
ListNode* findLoop(ListNode* head)
{
ListNode* slow = head;
ListNode* fast = head;
bool flag = false; //标志位,记录是否有环
while (fast->next && fast->next->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast) //快指针追上慢指针则有环
{
flag = true;
break;
}
}
if (flag) //有环返回入环节点
{
fast = head;
while (fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return fast;
}
else //无环返回空
{
return NULL;
}
}
//(2)判断两个无环链表是否相交,若相交返回相交节点,否则返回空
ListNode* noLoop(ListNode* head1, ListNode* head2)
{
ListNode* p1 = head1;
ListNode* p2 = head2;
while (p1 != p2)
{
p1 = p1 != NULL ? p1->next : head1;
p2 = p2 != NULL ? p2->next : head2;
}
return p1;
}
//(3)判断两个有环链表是否相交,若相交返回相交节点,否则返回空
ListNode* bothLoop(ListNode* head1, ListNode* loop1, ListNode* head2, ListNode* loop2)
{
//(3.1)入环节点相同,相交节点可能在环外,也可能就是这个入环节点
if (loop1 == loop2)
{
ListNode* p1 = head1;
ListNode* p2 = head2;
while (p1 != p2)
{
p1 = p1 != loop1 ? p1->next : head2;
p2 = p2 != loop2 ? p2->next : head1;
}
return p1;
}
//(3.2)入环节点不同,可能不想交,也可能相交在环内
else
{
ListNode* cur = loop1->next;
while (cur != loop1)
{
if (cur == loop2) // 相交在环内,返回loop1,或loop2均可
{
return loop1;
}
cur = cur->next;
}
return NULL; // 不相交
}
}
};
int main()
{
Solution* s = new Solution();
//simple01
// 1->2->3->4->5->6->7->null
ListNode* head1 = new ListNode(1);
head1->next = new ListNode(2);
head1->next->next = new ListNode(3);
head1->next->next->next = new ListNode(4);
head1->next->next->next->next = new ListNode(5);
head1->next->next->next->next->next = new ListNode(6);
head1->next->next->next->next->next->next = new ListNode(7);
// 0->9->8->6->7->null
ListNode* head2 = new ListNode(0);
head2->next = new ListNode(9);
head2->next->next = new ListNode(8);
head2->next->next->next = head1->next->next->next->next->next; // 8->6
cout << s->getIntersectNode(head1, head2)->val << endl;
//simple02
// 1->2->3->4->5->6->7->4...
head1 = new ListNode(1);
head1->next = new ListNode(2);
head1->next->next = new ListNode(3);
head1->next->next->next = new ListNode(4);
head1->next->next->next->next = new ListNode(5);
head1->next->next->next->next->next = new ListNode(6);
head1->next->next->next->next->next->next = new ListNode(7);
head1->next->next->next->next->next->next = head1->next->next->next; // 7->4
// 0->9->8->2...
head2 = new ListNode(0);
head2->next = new ListNode(9);
head2->next->next = new ListNode(8);
head2->next->next->next = head1->next; // 8->2
cout << s->getIntersectNode(head1, head2)->val << endl;
//simple03
// 0->9->8->6->4->5->6..
head2 = new ListNode(0);
head2->next = new ListNode(9);
head2->next->next = new ListNode(8);
head2->next->next->next = head1->next->next->next->next->next; // 8->6
cout << s->getIntersectNode(head1, head2)->val << endl;
system("pause");
return 0;
}