给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定的环,我们使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如果pos是-1,则在该链表中没有环。注意:pos不做为参数进行传递,仅仅是为了表示链表的实际情况,pos为-1或者链表中的一个有效索引
如果链表中存在环,则返回true,并返回环入口在链表中的位置、环的周长。否则,返回false。
示例1:
输入:[3,2,0,-4], 1
输出:
enterance index: 1
the perimeter of circular: 3
1
解释:链表中有一个环,其尾部连接到第二个节点
示例 2:
输入:head=[1,2], pos=0
输出:
enterance index: 0
the perimeter of circular: 2
1
解释:链表中有一个环,其尾部连接到第一个节点
示例3:
输入:head=[1],pos=-1
输出:
0
解释:链表中没有环。
题目分析:根据题目的示意图、输入输出示例,可以直观地看出题目所给的链表中是否有环,但是这里所给的示意图、输入输出示例,第一,是为了帮助读者理解题目,第二,是为了给出一些初始信息辅助读者构建算法的初始输入,链表中每个结点存储的数字对结果并没有什么影响,需关注的是单链表中有多少个结点,最后一个结点的next指针指向的位置。
解题思路:使用快慢指针,如果单链表中存在环,则快指针一定可以追上慢指针,如果不存在环,快指针在向前遍历的过程中,会遇到空指针。
代码如下所示:
#include <iostream>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
int getPosition(ListNode* head, ListNode* meeting) {
int index = 0;
ListNode* p1 = head;
ListNode* p2 = meeting;
while(p1 != p2) {
p1 = p1->next;
p2 = p2->next;
index++;
}
return index;
}
int getPerimter(ListNode* head) {
int len = 0;
ListNode* p = head;
do {
p = p->next;
len++;
} while(p != head);
return len;
}
bool hasCycle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
do {
if((fast == NULL) || (fast->next == NULL)) {
return false;
}
else {
fast = fast->next->next;
slow = slow->next;
}
} while(fast != slow);
int position = getPosition(head, fast);
cout << "enterance index: " << position << endl;
int len = getPerimter(fast);
cout << "the perimeter of ring: " << len << endl;
return true;
}
int main() {
vector<int> arr;
string line;
string temp;
while (getline(cin, line)) {
int i;
for (i = 0; i < line.size(); i++) {
if(line[i] == '[') {
continue;
}
if(line[i] == ',') {
arr.emplace_back(stoi(temp));
temp.clear();
continue;
}
if(line[i] == ']') {
arr.emplace_back(stoi(temp));
temp.clear();
break;
}
temp += line[i];
}
int key = stoi(line.substr(i + 2));
ListNode* head = NULL;
ListNode* lastNode = NULL;
for(int i = 0; i < arr.size(); i++) {
ListNode* node = new ListNode(arr[i]);
if(i == 0) {
head = node;
}
else {
lastNode->next = node;
}
lastNode = node;
}
ListNode* nextNode = head;
if(key > -1) {
while(key > 0) {
nextNode = nextNode->next;
key--;
}
lastNode->next = nextNode;
}
bool flag = hasCycle(head);
cout << flag << endl;
arr.clear();
head = NULL;
}
return 0;
}