环形链表 II
题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
输入输出样例
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
题解:
本题为简单题,但需要了解快慢指针的知识才能较快作出。这是对于链表找环路的问题的一个通用的解法。给定两个指针,分别命名为slow和fast,起始位置在链表的开头。每次fast前进两步,slow前进一步。如果fast可以走到尽头,那么说明没有环路;如果fast可以无限走下去,那么说明一定有环路,且一定存在一个时刻slow和fast相遇。然后我们再将fast重新移动到链表开头,并让slow和fast每次都前进一步。当slow和fast第二次相遇时,相遇的节点即为环路的开始点。具体解释可以参考LeetCode精品题解LeetCode题解
具体代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* detectCycle(ListNode* head) {
ListNode* slow = head, * fast = head;
//判断是否存在环路
do{
if(!fast || !fast->next) return nullptr;
fast = fast->next->next;
slow = slow->next;
}while(fast != slow);
//如果存在,查找环路节点
fast = head;
while(fast != slow){
slow = slow->next;
fast = fast->next;
}
return fast;
}
};