zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    C++--第12课
    C++--第11课
    C++--第10课
    C++--第9课
    C++--第8课
    C++--第7课
    鼠标
    MessageBox函数
    Windows对应的"Hello,world"程序
    网络上有哪些免费的教育资源?
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12713543.html
Copyright © 2011-2022 走看看