1、题目描述
给定一个带环的链表,找出链表中环的入口节点。
2、解题思路
(1)求出环中节点的总数
使用两个指针,一个快指针fast和一个慢指针slow,向前移动时,快指针每次移动两个节点,慢指针每次移动一个节点,当快指针和慢指针相等时,它们两此一次在环中相遇。接着,按照以上策略继续向前移动,同时用两个计数器分别统计快指针fast和慢指针slow的前进步数,当两个指针再次相遇时,快指针的步数减去慢指针的步数即为环中节点的总数count。
(2)求出环的入口节点
当已知环中节点的总数count时,接着使用两个指针进行移动。第一个指针先向前移动环的节点总数count步,此时两个指针刚好相差一个环的距离count。接着两个指针同时向前移动,当两个指针相等时,说明达到了环的入口节点。代码如下:
#include<iostream>
#include<vector>
using namespace std;
//定义链表节点
typedef struct LNode
{
int value;
struct LNode *next;
}LNode;
//指定链表节点总数和环入口,创建一个带环的链表
LNode* CreateList(int num,int circle) {
LNode *head = (LNode *)malloc(sizeof(LNode));
head->value = 0;
head->next = NULL;
LNode *entry_node = NULL;
LNode *end_node = head;
for (int i = 1; i < num; i++) {
LNode *node = (LNode *)malloc(sizeof(LNode));
node->value = i*i;
node->next = NULL;
end_node->next = node;
end_node = node;
if (i == circle)
entry_node = end_node;
}
end_node->next = entry_node;
return head;
}
//返回链表中环总共的节点数
int NodeNumOfCircle(LNode *head) {
LNode *slow = head;
LNode *fast = head;
int meet = 0;
int sum_slow = 0;
int sum_fast = 0;
while (1) {
fast = fast->next;
if (fast == slow)break;
fast = fast->next;
if (fast == slow)break;
slow = slow->next;
if (slow == fast)break;
}
while (1) {
fast = fast->next;
sum_fast++;
if (fast == slow)break;
fast = fast->next;
sum_fast++;
if (fast == slow)break;
slow = slow->next;
sum_slow++;
if (slow == fast)break;
}
return sum_fast - sum_slow;
}
//判断带环的链表中环的入口节点
void CircleInLinkedList() {
LNode *head = CreateList(10,8);
int num = NodeNumOfCircle(head);
LNode *p = head;
LNode *q = head;
while (num > 0) {
p = p->next;
num--;
}
while (p != q) {
p = p->next;
q = q->next;
}
cout << p->value<<endl;
}