457. Circular Array Loop

问题:

给定数组,nums[i]=k,k!=0

若k>0, 则下一个数的index是向右+|k|

若k<0,则下一个数的index是向左-|k|

(数组首尾相连)

这样的移动规则,问是否存在形成一个循环圈的访问环。(该环长度>1,且单向移动)

解法:

快慢指针法

慢指针一次移动一个,快指针一次移动两个,不断移动,若出现慢指针==快指针的时候,说明形成环

这里需要注意的:

1.应对nums[i]为负数的情况。

2.应对nums[i]为负数过大,mod之后还为负数的情况。

3.应对只对应同向移动

4.应对出现循环长度为1的情况

5.对不满足条件的置零操作。

参考代码:

 1 class Solution {
 2 public:
 3     int N;
 4     int getnext(vector<int>& nums, int i){
 5         int nextindex=0;
 6         nextindex=(i+nums[i]+N)%N;//1. +N:应对nums[i]为负数的情况。
 7         return nextindex;
 8     }
 9     bool circularArrayLoop(vector<int>& nums) {
10         int fast, slow;
11         N=nums.size();
12         int sign = 1;
13         for (int& n : nums) {
14             n %= N; // 2. 比如[-2,-3,-9]这样的情况,-9的下一个+N之后再mod N会得到一个负数,防止负数的情况,首先将数组的每个数,都限定在整个数组长度内。
15         }
16         for(int i=0; i<N; i++){
17             sign=nums[i]>0?1:-1;
18             slow=i;
19             fast=i;
20             while(true){
21                 if(nums[getnext(nums,fast)]*sign<=0 || nums[getnext(nums,getnext(nums,fast))]*sign<=0) break;
22                 //3. 要使得每次遍历的数字符号与第一个数nums[i]相同,则为同方向移动
23                 //这里,除了第一个nums[i],已经得到参照对象符号sign
24                 //从本次循环的,两个元素分别判断:
25                 //第二个元素getnext(nums,fast),第三个元素getnext(nums,getnext(nums,fast))
26                 slow=getnext(nums,slow);
27                 fast=getnext(nums,getnext(nums,fast));
28                 if(slow==fast){
29                     if(slow==getnext(nums,slow)) break;
30                     //4. 若出现循环,且其长度为1,则不满足条件,break
31                     return true;
32                 }
33             }
34             //5. 将不满足的【第一个元素i~最后一个<3或4的退出条件:开始反向移动 or 出现长度为1的循环>】
35             //将所有遍历过的数字置零,防止判断下一个数字重复判断同一个移动路径
36             //while(nums[k]*sign>0){ 可以满足同向移动,且没有被置零的路径,都进行置零
37             int k=i;
38             while(nums[k]*sign>0){
39                 int nexx=getnext(nums,k);
40                 nums[k]=0;
41                 k=nexx;
42             }
43         }
44         return false;
45     }
46 };
原文地址:https://www.cnblogs.com/habibah-chang/p/12713543.html