一、链表尾部重合
1、步骤
> 首先判断是否有环:【若有环,则返回入环结点】
方法1:可使用set容器,每次将链表结点压入时,进行查询;
方法2:使用快慢指针【快指针走两步,慢指针走一步】若走不到空结点,则有环。
且当两个指针相遇时,快指针回到头节点,两个指针每次走一步,当两个指针相遇时,
就是入环结点;
> 若链表无环:
两条无环链表,先进行长度判断。在将长的链表的前面多余部分去除,在与另一个链表进行循环
判断。
> 若链表有环且入环结点相等:
则重复上述无环操作;
> 若链表有环且入环结点不相等:
则让其中一个链表的入环结点开始循环,是否能遇到另一条入环结点,若可以则返回其中一个
即可,否则返回null
2、代码分块
2.1 数据结构
2.2 获取入环结点
2.3无环链表处理
2.4 有环链表处理
3、代码
#include <iostream>
typedef struct linkNode {
int val;
struct linkNode *next;
bool operator!= (struct linkNode *node) {
if(this->val != node->val || node->next != this->next)
return true;
return false;
}
bool operator==(struct linkNode *node) {
if(this->val != node->val || node->next != this->next)
return false;
return true;
}
}LinkNode;
LinkNode* getLoopNode(LinkNode *head) {
if(head == nullptr || head->next == nullptr || head->next->next == nullptr)
return nullptr;
LinkNode *n1 = head->next;
LinkNode *n2 = head->next->next;
while(n1 != n2) {
if(n2->next == nullptr || n2->next->next == nullptr)
return nullptr;
n2 = n2->next->next;
n1 = n1->next;
}
n2 = head;
while(n1 != n2) {
n1 = n1->next;
n2 = n2->next;
}
return n1;
}
LinkNode* noLoop(LinkNode *head1, LinkNode *head2) {
if(head1 == nullptr || head2 == nullptr)
return nullptr;
LinkNode *cur1 = head1;
LinkNode *cur2 = head2;
int n = 0;
while(cur1->next != nullptr) {
n++;
cur1 = cur1->next;
}
while(cur2->next != nullptr) {
n--;
cur2 = cur2->next;
}
if(cur1 != cur2) {
return nullptr;
}
cur1 = n > 0 ? head1 : head2;
cur2 = cur1 == head1 ? head2 : head1;
n = abs(n);
while(n != 0) {
n--;
cur1 = cur1->next;
}
while(cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
LinkNode* bothLoop(LinkNode *head1, LinkNode *loop1, LinkNode *head2, LinkNode *loop2) {
LinkNode *cur1 = nullptr;
LinkNode *cur2 = nullptr;
if(loop1 == loop2) {
cur1 = head1;
cur2 = head2;
int n=0;
while(cur1 != loop1) {
n++;
cur1 = cur1->next;
}
while(cur2 != loop2) {
n--;
cur2 = cur2->next;
}
cur1 = n > 0 ? head1 : head2;
cur2 = cur1 == head1 ? head2 : head1;
n = abs(n);
while(n != 0) {
n--;
cur1 = cur1->next;
}
while(cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
} else {
cur1 = loop1->next;
while(cur1 != loop1) {
if(cur1 == loop2)
return loop1;
cur1 = cur1->next;
}
return nullptr;
}
}
LinkNode* getIntersectNode(LinkNode *head1, LinkNode *head2) {
if(head1 == nullptr || head2 == nullptr)
return nullptr;
LinkNode *loop1 = getLoopNode(head1);
LinkNode *loop2 = getLoopNode(head2);
if(loop1 == nullptr && loop2 == nullptr)
return noLoop(head1, head2);
if(loop1 != nullptr && loop2 != nullptr)
return bothLoop(head1, loop1, head2, loop2);
return nullptr;
}
int main(int argc, char* argv[])
{
LinkNode *Node1 = new LinkNode[10];
LinkNode *Node2 = new LinkNode[10];
LinkNode n1, n2, n3, n4, n5, n6, n7, n8, n9, nn1, nn2, nn3;
n1.val = 10;
n2.val = 3;
n3.val = 5;
n4.val = 2;
n5.val = 8;
n6.val = 7;
n7.val = 6;
n8.val = 9;
n9.val = 1;
nn1.val = 11;
nn2.val = 23;
nn3.val = 12;
Node1->next = &n1;
n1.next = &n2;
n2.next = &n3;
n3.next = &n4;
n4.next = &n5;
n5.next = &n6;
n6.next = &n7;
n7.next = &n8;
n8.next = &n9;
n9.next = nullptr;
Node2->next = &nn1;
nn1.next = &nn2;
nn2.next = &nn3;
nn3.next = &n4;
LinkNode *tmp1 = new LinkNode;
tmp1 = Node1;
while(tmp1->next != nullptr) {
tmp1 = tmp1->next;
std::cout << tmp1->val << " ";
}
std::cout << std::endl;
LinkNode *tmp2 = new LinkNode;
tmp2 = Node2;
while(tmp2->next != nullptr) {
tmp2 = tmp2->next;
std::cout << tmp2->val << " ";
}
std::cout << std::endl;
LinkNode *ret = new LinkNode;
ret = getIntersectNode(Node1, Node2);
std::cout << ret->val << std::endl;
return 0;
}