Open In App

Count of elements which form a loop in an Array according to given constraints

Given an array A containing N integers, the task is to count the number of elements which form a cycle in the array, based on the following condition. 
Start to traverse the Array from index i and jump to its next connected index. A directed edge exits from index i of A to index j if j = GCD(i, A[i]) % N. If on traversing array in the described order, index i is again visited then index i is said to form a cycle in an array. 
Examples:

Input: A = { 1, 1, 6, 2 } 
Output:
Explanation: 
Possible traversals with the given condition are: 
0 -> 1 -> 1 
1 -> 1 
2 -> 2 
3 -> 2 -> 2 
Clearly, only vertices 1 and 2 forms a cycle.
Input: A = {0, 0, 0, 6} 
Output:
Explanation: 
Possible traversals with the given condition are: 
0 -> 0 
1 -> 1 
2 -> 2 
3 -> 3 
Clearly, all the vertices forms a cycle.

Approach: 
To solve the problem mentioned above, we have to assume that each index represents a single node of the graph.

In the worst case, every node will be traversed at most 3 times. Hence solution has linear time complexity.
Below is the implementation of above approach:




// C++ program to number of elements
// which form a cycle in an array
 
#include <bits/stdc++.h>
using namespace std;
 
#define mp make_pair
#define pb push_back
#define mod 1000000007
 
// Function to count number of
// elements forming a cycle
int solve(int A[], int n)
{
    int i, cnt = 0, j;
 
    // Array to store parent
    // node of traversal.
    int parent[n];
 
    // Array to determine
    // whether current node
    // is already counted
    // in the cycle.
    int vis[n];
 
    // Initialize the arrays.
    memset(parent, -1, sizeof(parent));
    memset(vis, 0, sizeof(vis));
 
    for (i = 0; i < n; i++) {
        j = i;
 
        // Check if current node is already
        // traversed or not. If node is not
        // traversed yet then parent value
        // will be -1.
        if (parent[j] == -1) {
 
            // Traverse the graph until an
            // already visited node is not
            // found.
            while (parent[j] == -1) {
                parent[j] = i;
                j = __gcd(j, A[j]) % n;
            }
 
            // Check parent value to ensure
            // a cycle is present.
            if (parent[j] == i) {
 
                // Count number of nodes in
                // the cycle.
                while (!vis[j]) {
                    vis[j] = 1;
                    cnt++;
                    j = __gcd(j, A[j]) % n;
                }
            }
        }
    }
 
    return cnt;
}
 
int main()
{
    int A[] = { 1, 1, 6, 2 };
    int n = sizeof(A) / sizeof(A[0]);
    cout << solve(A, n);
    return 0;
}




// Java program to number of elements
// which form a cycle in an array
import java.util.*;
class GFG{
 
static final int mod = 1000000007;
 
// Function to count number of
// elements forming a cycle
static int solve(int A[], int n)
{
    int i, cnt = 0, j;
 
    // Array to store parent
    // node of traversal.
    int []parent = new int[n];
 
    // Array to determine
    // whether current node
    // is already counted
    // in the cycle.
    int []vis = new int[n];
 
    // Initialize the arrays.
    Arrays.fill(parent, -1);
    Arrays.fill(vis, 0);
 
    for(i = 0; i < n; i++)
    {
        j = i;
 
        // Check if current node is already
        // traversed or not. If node is not
        // traversed yet then parent value
        // will be -1.
        if (parent[j] == -1)
        {
 
            // Traverse the graph until an
            // already visited node is not
            // found.
            while (parent[j] == -1)
            {
                parent[j] = i;
                j = __gcd(j, A[j]) % n;
            }
 
            // Check parent value to ensure
            // a cycle is present.
            if (parent[j] == i)
            {
 
                // Count number of nodes in
                // the cycle.
                while (vis[j] == 0)
                {
                    vis[j] = 1;
                    cnt++;
                    j = __gcd(j, A[j]) % n;
                }
            }
        }
    }
    return cnt;
}
 
static int __gcd(int a, int b)
{
    return b == 0 ? a : __gcd(b, a % b);    
}
 
// Driver code
public static void main(String[] args)
{
    int A[] = { 1, 1, 6, 2 };
    int n = A.length;
     
    System.out.print(solve(A, n));
}
}
 
// This code is contributed by gauravrajput1




# Python3 program to number of elements
# which form a cycle in an array
import math
 
mod = 1000000007
 
# Function to count number of
# elements forming a cycle
def solve(A, n):
     
    cnt = 0
 
    # Array to store parent
    # node of traversal.
    parent = [-1] * n
 
    # Array to determine
    # whether current node
    # is already counted
    # in the cycle.
    vis = [0] * n
 
    for i in range(n):
        j = i
 
        # Check if current node is already
        # traversed or not. If node is not
        # traversed yet then parent value
        # will be -1.
        if (parent[j] == -1):
 
            # Traverse the graph until an
            # already visited node is not
            # found.
            while (parent[j] == -1):
                parent[j] = i
                j = math.gcd(j, A[j]) % n
             
            # Check parent value to ensure
            # a cycle is present.
            if (parent[j] == i):
 
                # Count number of nodes in
                # the cycle.
                while (vis[j] == 0):
                    vis[j] = 1
                    cnt += 1
                    j = math.gcd(j, A[j]) % n
                     
    return cnt
 
# Driver code
A = [ 1, 1, 6, 2 ]
n = len(A)
 
print(solve(A, n))
 
# This code is contributed by sanjoy_62




// C# program to number of elements
// which form a cycle in an array
using System;
 
class GFG{
     
// Function to count number of
// elements forming a cycle
static int solve(int[] A, int n)
{
    int i, cnt = 0, j;
 
    // Array to store parent
    // node of traversal.
    int[] parent = new int[n];
 
    // Array to determine
    // whether current node
    // is already counted
    // in the cycle.
    int[] vis = new int[n];
 
    // Initialize the arrays.
    Array.Fill(parent, -1);
    Array.Fill(vis, 0);
 
    for(i = 0; i < n; i++)
    {
        j = i;
 
        // Check if current node is already
        // traversed or not. If node is not
        // traversed yet then parent value
        // will be -1.
        if (parent[j] == -1)
        {
             
            // Traverse the graph until an
            // already visited node is not
            // found.
            while (parent[j] == -1)
            {
                parent[j] = i;
                j = __gcd(j, A[j]) % n;
            }
 
            // Check parent value to ensure
            // a cycle is present.
            if (parent[j] == i)
            {
 
                // Count number of nodes in
                // the cycle.
                while (vis[j] == 0)
                {
                    vis[j] = 1;
                    cnt++;
                    j = __gcd(j, A[j]) % n;
                }
            }
        }
    }
    return cnt;
}
 
static int __gcd(int a, int b)
{
    return b == 0 ? a : __gcd(b, a % b);    
}
 
// Driver code
static void Main()
{
    int[] A = { 1, 1, 6, 2 };
    int n = A.Length;
     
    Console.WriteLine(solve(A, n));
}
}
 
// This code is contributed by divyeshrabadiya07




<script>
 
    // JavaScript program to number of elements
    // which form a cycle in an array
     
    // Function to count number of
    // elements forming a cycle
    function solve(A, n)
    {
        let i, cnt = 0, j;
 
        // Array to store parent
        // node of traversal.
        let parent = new Array(n);
 
        // Array to determine
        // whether current node
        // is already counted
        // in the cycle.
        let vis = new Array(n);
 
        // Initialize the arrays.
        parent.fill(-1);
        vis.fill(0);
 
        for(i = 0; i < n; i++)
        {
            j = i;
 
            // Check if current node is already
            // traversed or not. If node is not
            // traversed yet then parent value
            // will be -1.
            if (parent[j] == -1)
            {
 
                // Traverse the graph until an
                // already visited node is not
                // found.
                while (parent[j] == -1)
                {
                    parent[j] = i;
                    j = __gcd(j, A[j]) % n;
                }
 
                // Check parent value to ensure
                // a cycle is present.
                if (parent[j] == i)
                {
 
                    // Count number of nodes in
                    // the cycle.
                    while (vis[j] == 0)
                    {
                        vis[j] = 1;
                        cnt++;
                        j = __gcd(j, A[j]) % n;
                    }
                }
            }
        }
        return cnt;
    }
 
    function __gcd(a, b)
    {
        return b == 0 ? a : __gcd(b, a % b);    
    }
     
    let A = [ 1, 1, 6, 2 ];
    let n = A.length;
       
    document.write(solve(A, n));
 
</script>

Output: 
2

Time Complexity: O(N)
Space Complexity: O(N)
 


Article Tags :