Given an array A of integers. Index i of A is said to be connected to index j if j = (i + A[i]) % n + 1 (Assume 1-based indexing). Start traversing array from index i and jump to its next connected index. If on traversing array in the described order, index i is again visited then index i is a magical index. Count the number of magical indexes in the array. Assume that array A consists of non-negative integers.
Examples :
Input : A = {1, 1, 1, 1}
Output : 4
Possible traversals:
1 -> 3 -> 1
2 -> 4 -> 2
3 -> 1 -> 3
4 -> 2 -> 4
Clearly all the indices are magical
Input : A = {0, 0, 0, 2}
Output : 2
Possible traversals:
1 -> 2 -> 3 -> 4 -> 3...
2 -> 3 -> 4 -> 3...
3 -> 4 -> 3
4 -> 3 ->4
Magical indices = 3, 4
Approach: The problem is of counting number of nodes in all the cycles present in the graph. Each index represents a single node of the graph. Each node has a single directed edge as described in the problem statement. This graph has a special property: On starting a traversal from any vertex, a cycle is always detected. This property will be helpful in reducing the time complexity of the solution.
Read this post on how to detect cycle in a directed graph: Detect Cycle in directed graph
Let the traversal begins from node i. Node i will be called parent node of this traversal and this parent node will be assigned to all the nodes visited during traversal. While traversing the graph if we discover a node that is already visited and parent node of that visited node is same as parent node of the traversal then a new cycle is detected. To count number of nodes in this cycle, start another dfs from this node until this same node is not visited again. This procedure is repeated for every node i of the graph. In worst case every node will be traversed at most 3 times. Hence solution has linear time complexity.
The stepwise algorithm is:
1. For each node in the graph:
if node i is not visited then:
for every adjacent node j:
if node j is not visited:
par[j] = i
else:
if par[j]==i
cycle detected
count nodes in cycle
2. return count
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define mod 1000000007
int solve( int A[], int n)
{
int i, cnt = 0, j;
int parent[n + 1];
int vis[n + 1];
memset (parent, -1, sizeof (parent));
memset (vis, 0, sizeof (vis));
for (i = 0; i < n; i++) {
j = i;
if (parent[j] == -1) {
while (parent[j] == -1) {
parent[j] = i;
j = (j + A[j] + 1) % n;
}
if (parent[j] == i) {
while (!vis[j]) {
vis[j] = 1;
cnt++;
j = (j + A[j] + 1) % n;
}
}
}
}
return cnt;
}
int main()
{
int A[] = { 0, 0, 0, 2 };
int n = sizeof (A) / sizeof (A[0]);
cout << solve(A, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
public class GFG {
static int solve( int []A, int n)
{
int i, cnt = 0 , j;
int []parent = new int [n + 1 ];
int []vis = new int [n + 1 ];
for (i = 0 ; i < n+ 1 ; i++) {
parent[i] = - 1 ;
vis[i] = 0 ;
}
for (i = 0 ; i < n; i++) {
j = i;
if (parent[j] == - 1 ) {
while (parent[j] == - 1 ) {
parent[j] = i;
j = (j + A[j] + 1 ) % n;
}
if (parent[j] == i) {
while (vis[j]== 0 ) {
vis[j] = 1 ;
cnt++;
j = (j + A[j] + 1 ) % n;
}
}
}
}
return cnt;
}
public static void main(String args[])
{
int []A = { 0 , 0 , 0 , 2 };
int n = A.length;
System.out.print(solve(A, n));
}
}
|
Python3
def solve(A, n) :
cnt = 0
parent = [ None ] * (n + 1 )
vis = [ None ] * (n + 1 )
for i in range ( 0 , n + 1 ):
parent[i] = - 1
vis[i] = 0
for i in range ( 0 , n):
j = i
if (parent[j] = = - 1 ) :
while (parent[j] = = - 1 ) :
parent[j] = i
j = (j + A[j] + 1 ) % n
if (parent[j] = = i) :
while (vis[j] = = 0 ) :
vis[j] = 1
cnt = cnt + 1
j = (j + A[j] + 1 ) % n
return cnt
A = [ 0 , 0 , 0 , 2 ]
n = len (A)
print (solve(A, n))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int solve( int []A, int n)
{
int i, cnt = 0, j;
int []parent = new int [n + 1];
int []vis = new int [n + 1];
for (i = 0; i < n+1; i++) {
parent[i] = -1;
vis[i] = 0;
}
for (i = 0; i < n; i++) {
j = i;
if (parent[j] == -1) {
while (parent[j] == -1) {
parent[j] = i;
j = (j + A[j] + 1) % n;
}
if (parent[j] == i) {
while (vis[j]==0) {
vis[j] = 1;
cnt++;
j = (j + A[j] + 1) % n;
}
}
}
}
return cnt;
}
public static void Main()
{
int []A = { 0, 0, 0, 2 };
int n = A.Length;
Console.WriteLine(solve(A, n));
}
}
|
PHP
<?php
function solve( $A , $n )
{
$i = 0;
$cnt = 0;
$j = 0;
$parent = array ();
$vis = array ();
for ( $i = 0; $i < $n + 1; $i ++)
{
$parent [ $i ] = -1;
$vis [ $i ] = 0;
}
for ( $i = 0; $i < $n ; $i ++)
{
$j = $i ;
if ( $parent [ $j ] == -1)
{
while ( $parent [ $j ] == -1)
{
$parent [ $j ] = $i ;
$j = ( $j + $A [ $j ] + 1) % $n ;
}
if ( $parent [ $j ] == $i )
{
while ( $vis [ $j ] == 0)
{
$vis [ $j ] = 1;
$cnt ++;
$j = ( $j + $A [ $j ] + 1) % $n ;
}
}
}
}
return $cnt ;
}
$A = array ( 0, 0, 0, 2 );
$n = count ( $A );
echo (solve( $A , $n ));
?>
|
Javascript
<script>
mod = 1000000007
function solve(A, n)
{
var i, cnt = 0, j;
var parent = new Array(n + 1);
var vis = new Array(n + 1);
parent.fill(-1);
vis.fill(0);
for (i = 0; i < n; i++)
{
j = i;
if (parent[j] == -1)
{
while (parent[j] == -1)
{
parent[j] = i;
j = (j + A[j] + 1) % n;
}
if (parent[j] == i)
{
while (!vis[j])
{
vis[j] = 1;
cnt++;
j = (j + A[j] + 1) % n;
}
}
}
}
return cnt;
}
var A = [ 0, 0, 0, 2 ];
var n = A.length;
document.write(solve(A, n));
</script>
|
Complexity Analysis:
- Time Complexity: O(n)
- Space Complexity: O(n)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
14 Sep, 2022
Like Article
Save Article