457. Circular Array Loop

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, move nums[i] steps forward, and
  • If nums[i] is negative, move nums[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.

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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值