Total number of components in the index Array
Last Updated :
21 Sep, 2023
Given an array arr[] of N integers of value from 0 to N, the task is to count the number of components in Index Array.
Index array means if we are at ith index then it leads to arr[i].
The component of an index array is counted when it forms a cycle. If no cycle persists or the array contains a single element then also we consider it as a component.
For Example:
Let array arr[] = {1, 2, 0, 3}
{1, 2, 0} will form one component as starting from index 0 we reach the index 0 again as:
1 -> 2(arr[1]) -> 0(arr[2]) -> 1(arr[0])
Examples:
Input: arr[] = {1, 2, 3, 5, 0, 4, 6}
Output: 2
Explanation:
Below is the traversal of the 2 components:
Component 1: Start traversal from 0, then the path of traversal is given by:
1 -> 2(arr[1]) -> 3(arr[2]) -> 5(arr[3]) -> 4(arr[5]) -> 0(arr[4]) -> 1(arr[0]).
Component 2: Only 6 is unvisited it creates one more component.
So, the total components = 2.
Input: arr[] = {1, 2, 0, 3}
Output: 2
Explanation:
Below is the traversal of the 2 components:
Component 1: Start traversal from 0, then the path of traversal is given by:
1 -> 2(arr[1]) -> 0(arr[2]) -> 1(arr[0])
Component 2: Only 3 is unvisited it creates one more component.
So, the total components = 2.
Approach: The idea is to use the concept of DFS traversal. Below are the steps:
- Start from the first unvisited index which will be index with integer 0 in it.
- During DFS Traversal mark the visited elements in the array until the elements form a cycle.
- If a cycle is formed then it means that we have got one component and hence increase the component count.
- Repeat all the above steps for all the unvisited index in the array and count the total components in the given index array.
- If all the index of the array are visited, then print the total count of connected components.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > visited;
void dfs( int i, int a[])
{
if (visited[i] == 0) {
visited[i] = 1;
dfs(a[i], a);
}
return ;
}
int allvisited( int a[], int n)
{
for ( int i = 0; i < n; i++) {
if (visited[i] == 0)
return i;
}
return -1;
}
int count( int a[], int n)
{
int c = 0;
int x = allvisited(a, n);
while (x != -1) {
c++;
dfs(x, a);
x = allvisited(a, n);
}
cout << c << endl;
}
int main()
{
int arr[] = { 1, 4, 3, 5, 0, 2, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
visited = vector< int >(N+1,0);
count(arr, N);
return 0;
}
|
Java
import java.util.*;
class Main
{
static void dfs( int i, int [] a,
HashMap<Integer, Integer> m)
{
if (!m.containsKey(i))
{
m.put(i, 1 );
dfs(a[i], a, m);
}
return ;
}
static int allvisited( int [] a, int n,
HashMap<Integer, Integer> m)
{
for ( int i = 0 ; i < n; i++)
{
if (!m.containsKey(i))
return i;
}
return - 1 ;
}
static void count( int [] a, int n)
{
int c = 0 ;
HashMap<Integer, Integer> m = new HashMap<>();
int x = allvisited(a, n, m);
while (x != - 1 )
{
c++;
dfs(x, a, m);
x = allvisited(a, n, m);
}
System.out.print(c);
}
public static void main(String[] args)
{
int [] arr = { 1 , 4 , 3 , 5 , 0 , 2 , 6 };
int N = arr.length;
count(arr, N);
}
}
|
Python3
def dfs(i, a, m):
if i in m:
if m[i] = = 0 :
m[i] = 1
dfs(a[i], a, m)
else :
m[i] = 1
dfs(a[i], a, m)
return
def allvisited(a, n, m):
for i in range (n):
if i in m:
if m[i] = = 0 :
return i
else :
return i
return - 1
def count(a, n):
c = 0
m = dict ()
x = allvisited(a, n, m)
while (x ! = - 1 ):
c + = 1
dfs(x, a, m)
x = allvisited(a, n, m)
print (c)
if __name__ = = '__main__' :
arr = [ 1 , 4 , 3 , 5 , 0 , 2 , 6 ]
N = len (arr)
count(arr, N)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
static void dfs( int i, int []a,
Dictionary< int , int > m)
{
if (!m.ContainsKey(i))
{
m[i] = 1;
dfs(a[i], a, m);
}
return ;
}
static int allvisited( int []a, int n,
Dictionary< int , int > m)
{
for ( int i = 0; i < n; i++)
{
if (!m.ContainsKey(i))
return i;
}
return -1;
}
static void count( int []a, int n)
{
int c = 0;
Dictionary< int ,
int > m = new Dictionary< int ,
int >();
int x = allvisited(a, n, m);
while (x != -1)
{
c++;
dfs(x, a, m);
x = allvisited(a, n, m);
}
Console.Write(c);
}
public static void Main()
{
int []arr = { 1, 4, 3, 5, 0, 2, 6 };
int N = arr.Length;
count(arr, N);
}
}
|
Javascript
<script>
function dfs(i, a, m)
{
if (!m.has(i)) {
m.set(i, 1);
m[i] = 1;
dfs(a[i], a, m);
}
return ;
}
function allvisited(a, n, m)
{
for ( var i = 0; i < n; i++) {
if (!m.has(i))
return i;
}
return -1;
}
function count(a, n)
{
var c = 0;
var m = new Map();
var x = allvisited(a, n, m);
while (x != -1) {
c++;
dfs(x, a, m);
x = allvisited(a, n, m);
}
document.write( c );
}
var arr = [1, 4, 3, 5, 0, 2, 6];
var N = arr.length;
count(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Approach: Union-Find
The Union-Find, also known as the Disjoint-Set data structure, is a data structure and algorithm used to efficiently perform operations on disjoint sets of elements. It provides two main operations find and union.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <vector>
using namespace std;
int find(vector< int >& parent, int i)
{
if (parent[i] == i)
return i;
return find(parent, parent[i]);
}
void unionSet(vector< int >& parent, int i, int j)
{
int rootA = find(parent, i);
int rootB = find(parent, j);
if (rootA != rootB)
parent[rootA] = rootB;
}
int countComponents(vector< int >& arr)
{
int N = arr.size();
vector< int > parent(N);
for ( int i = 0; i < N; i++)
parent[i] = i;
int componentCount = N;
for ( int i = 0; i < N; i++) {
int rootA = find(parent, i);
int rootB = find(parent, arr[i]);
if (rootA != rootB) {
unionSet(parent, rootA, rootB);
componentCount--;
}
}
return componentCount;
}
int main()
{
vector< int > arr = { 1, 2, 3, 5, 0, 4, 6 };
int result = countComponents(arr);
cout << result << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.Arrays;
class Main {
static int find( int [] parent, int i) {
if (parent[i] == i)
return i;
return find(parent, parent[i]);
}
static void unionSet( int [] parent, int i, int j) {
int rootA = find(parent, i);
int rootB = find(parent, j);
if (rootA != rootB)
parent[rootA] = rootB;
}
static int countComponents( int [] arr) {
int N = arr.length;
int [] parent = new int [N];
for ( int i = 0 ; i < N; i++)
parent[i] = i;
int componentCount = N;
for ( int i = 0 ; i < N; i++) {
int rootA = find(parent, i);
int rootB = find(parent, arr[i]);
if (rootA != rootB) {
unionSet(parent, rootA, rootB);
componentCount--;
}
}
return componentCount;
}
public static void main(String[] args) {
int [] arr = { 1 , 2 , 3 , 5 , 0 , 4 , 6 };
int result = countComponents(arr);
System.out.println(result);
}
}
|
Python
def GFG(parent, i):
if parent[i] = = i:
return i
return GFG(parent, parent[i])
def union_set(parent, i, j):
root_a = GFG(parent, i)
root_b = GFG(parent, j)
if root_a ! = root_b:
parent[root_a] = root_b
def count_components(arr):
N = len (arr)
parent = list ( range (N))
component_count = N
for i in range (N):
root_a = GFG(parent, i)
root_b = GFG(parent, arr[i])
if root_a ! = root_b:
union_set(parent, root_a, root_b)
component_count - = 1
return component_count
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 5 , 0 , 4 , 6 ]
result = count_components(arr)
print (result)
|
C#
using System;
using System.Collections.Generic;
public class MainClass
{
public static int Find(List< int > parent, int i)
{
if (parent[i] == i)
return i;
return Find(parent, parent[i]);
}
public static void UnionSet(List< int > parent, int i, int j)
{
int rootA = Find(parent, i);
int rootB = Find(parent, j);
if (rootA != rootB)
parent[rootA] = rootB;
}
public static int CountComponents(List< int > arr)
{
int N = arr.Count;
List< int > parent = new List< int >(N);
for ( int i = 0; i < N; i++)
parent.Add(i);
int componentCount = N;
for ( int i = 0; i < N; i++)
{
int rootA = Find(parent, i);
int rootB = Find(parent, arr[i]);
if (rootA != rootB)
{
UnionSet(parent, rootA, rootB);
componentCount--;
}
}
return componentCount;
}
public static void Main( string [] args)
{
List< int > arr = new List< int > { 1, 2, 3, 5, 0, 4, 6 };
int result = CountComponents(arr);
Console.WriteLine(result);
}
}
|
Javascript
function find(parent, i) {
if (parent[i] === i) {
return i;
}
return find(parent, parent[i]);
}
function unionSet(parent, i, j) {
const rootA = find(parent, i);
const rootB = find(parent, j);
if (rootA !== rootB) {
parent[rootA] = rootB;
}
}
function countComponents(arr) {
const N = arr.length;
const parent = new Array(N);
for (let i = 0; i < N; i++) {
parent[i] = i;
}
let componentCount = N;
for (let i = 0; i < N; i++) {
const rootA = find(parent, i);
const rootB = find(parent, arr[i]);
if (rootA !== rootB) {
unionSet(parent, rootA, rootB);
componentCount--;
}
}
return componentCount;
}
const arr = [1, 2, 3, 5, 0, 4, 6];
const result = countComponents(arr);
console.log(result);
|
Time Complexity: O(N), where N is the size of the input array
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...