题目链接:https://leetcode-cn.com/problems/circular-array-loop/
快慢指针法,由于题目要求循环内必须为同向,所以限制条件要使每一步的下标及其对应元素同符号。
为简化时间复杂度,每遍历完一个点及其可到达的点后,若没有发现循环,则将其及其可达点都标记为0.
代码如下:
class Solution {
public:
bool circularArrayLoop(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
if (nums[i] == 0) continue;
int slow = i, fast = getNext(nums, i), val = nums[i];
while (val * nums[fast] > 0 && val * nums[getNext(nums, fast)] > 0) {
if (slow == fast) {
if (slow == getNext(nums, slow)) break;
return true;
}
slow = getNext(nums, slow);
fast = getNext(nums, getNext(nums, fast));
}
slow = i;
while (val * nums[slow] > 0) { //类似于剪枝,标记为0
int next = getNext(nums, slow);
nums[slow] = 0;
slow = next;
}
}
return false;
}
int getNext(vector<int>& nums, int i) { //找下一个元素
int n = nums.size();
return (((nums[i] + i) % n) + n) % n;
}
};