Circular Array Loop in C++


Suppose we have a circular array nums of positive and negative integer values. If a number k at an index is a positive number, then move forward k steps. Otherwise, if it's negative (-k), move backward k steps. Since the array is circular, we can assume that the next element of the last element is the first element, and the previous element of the first element is the last element. We have to check whether if there is a loop (or a cycle) in nums. A cycle must start and end at the same index and the cycle's length > 1. So if the input is like [2,-1,1,2,2], then the output will be true, as there is a cycle from index 0 -> 2 -> 3 -> 0 of length 3.

To solve this, we will follow these steps −

  • n := size of nums


  • if n < 2, then return false


  • for i in range 0 to n - 1, nums[i] := nums[i] mod n

  • for i in range 0 to n – 1

    • if nums[i] = 0, then go for next iteration continue;

    • slow = i, fast = i;

    • while nums[slow] * nums[fast] > 0 and nums[next of fast] * nums[slow] > 0

      • slow = next of slow

      • fast := next of the next of fast

      • if slow = fast, then

        • if slow = next of slow, then come out from the loop

        • return true

    • x := nums[i]

    • slow := i

    • while nums[slow] * x > 0

      • temp := next of slow

      • next of slow := 0

      • slow := temp

  • return false

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   int next(vector<int>& nums, int i){
      int n = nums.size();
      return (n+nums[i]+i)%n;
   }
   bool circularArrayLoop(vector<int>& nums) {
      int n = nums.size();
      if(n < 2) return false;
      for(int i = 0; i < n; i++)nums[i] %= n;
      for(int i = 0; i < n; i++){
         if(nums[i] == 0) continue;
         int slow = i;
         int fast = i;
         while(nums[slow] * nums[fast] > 0 && nums[next(nums, fast)] * nums[slow] > 0){
            slow = next(nums, slow);
            fast = next(nums, next(nums, fast));
            if(slow == fast){
               if(slow == next(nums, slow))
               break;
               return true;
            }
         }
         int x = nums[i];
         slow = i;
         while(nums[slow] * x > 0){
            int temp = next(nums, slow);
            nums[slow] = 0;
            slow = temp;
         }
      }
      return false;
   }
};
main(){
   vector<int> v = {2,-1,1,2,2};
   Solution ob;
   cout << (ob.circularArrayLoop(v));
}

Input

[2,-1,1,2,2]

Output

1

Updated on: 30-Apr-2020

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements