You are playing a game involving a circular array of non-zero integers nums
. Each nums[i]
denotes the number of indices forward/backward you must move if you are located at index i
:
- If
nums[i]
is positive, movenums[i]
steps forward, and - If
nums[i]
is negative, movenums[i]
steps backward.
Since the array is circular, you may assume that moving forward from the last element puts you on the first element, and moving backwards from the first element puts you on the last element.
A cycle in the array consists of a sequence of indices seq
of length k
where:
- Following the movement rules above results in the repeating index sequence
seq[0] -> seq[1] -> ... -> seq[k - 1] -> seq[0] -> ...
- Every
nums[seq[j]]
is either all positive or all negative. k > 1
Return true
if there is a cycle in nums
, or false
otherwise.
Example 1:
Input: nums = [2,-1,1,2,2] Output: true Explanation: There is a cycle from index 0 -> 2 -> 3 -> 0 -> ... The cycle's length is 3.
Example 2:
Input: nums = [-1,2] Output: false Explanation: The sequence from index 1 -> 1 -> 1 -> ... is not a cycle because the sequence's length is 1. By definition the sequence's length must be strictly greater than 1 to be a cycle.
Example 3:
Input: nums = [-2,1,-1,-2,-2] Output: false Explanation: The sequence from index 1 -> 2 -> 1 -> ... is not a cycle because nums[1] is positive, but nums[2] is negative. Every nums[seq[j]] must be either all positive or all negative.
Constraints:
1 <= nums.length <= 5000
-1000 <= nums[i] <= 1000
nums[i] != 0
题目:给一个非零数组,nums[i]大于零时向前跳,小于零时向后跳。问数组中是否有环,就是能跳到起始点的环,这里的起始点是起跳点,不一定在index=0的位置,而且环中所有元素的符号值需要一致。向前跳就一直向前跳,向后跳就一直向后跳。
思路:由于没有指定起始点,所以需要从每个元素都遍历到。但如果元素值已经被遍历过了,则不需再遍历。因此需要给遍历过的位置做标记,为避免每次遍历元素值混淆造成结果不正确,每次遍历的标记值需不同。
代码:
class Solution {
public:
//更新坐标位置
int update(int p, int num, int n){
p += num;
while(p < 0) p += n;
p %= n;
}
bool isCircular(vector<int>& nums, vector<int>& record, int p){
int n = p+1; //计算标签值
while(record[p] == 0){
record[p] = n;
p = update(p, nums[p], nums.size());
}
if(record[p] != n) return false; //p为环顶点,若遍历到其它环中,返回
int p1 = update(p, nums[p], nums.size());
if(p1 == p) return false;
while(p1 != p){
if(nums[p1] * nums[p] < 0) return false; //判断是否同号
p1 = update(p1, nums[p1], nums.size());
}
return true;
}
bool circularArrayLoop(vector<int>& nums) {
vector<int> record(nums.size(), 0);
for(int i = 0; i < nums.size(); i++){
if(record[i] == 1) continue;
if(isCircular(nums, record, i)) return true;
}
return false;
}
};