Minimum time to return array to its original state after given modifications
Last Updated :
12 Sep, 2022
Given two arrays of integers arr and P such that after a cycle an element arr[i] will be at location arr[P[i]]. The task is to find the minimum number of cycles after that all the elements of the array have returned to their original locations.
Examples:
Input: arr[] = {1, 2, 3}, P[] = {3, 2, 1}
Output: 2
After first move array will be {3, 2, 1}
after second move array will be {1, 2, 3}
Input: arr[] = {4, 5, 1, 2, 3}, P[] = {1, 4, 2, 5, 3}
Output: 4
Approach: This problem seems to be a typical mathematical problem but if we carefully observe it then we will find that we have to find only the permutation cycles i.e. connected components (formed by the cycles from element movements) and number of nodes in each connected component will represent the time in which the integers will be back in it’s original position for that particular cycle.
For overall graph, do the LCM of the count of nodes from every connected component which is the answer.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int lcm( int a, int b)
{
return (a * b) / (__gcd(a, b));
}
int dfs( int src, vector< int > adj[], vector< bool > &visited)
{
visited[src] = true ;
int count = 1;
for ( int i = 0; i < adj[src].size(); i++)
if (!visited[adj[src][i]])
count += dfs(adj[src][i], adj, visited);
return count;
}
int findMinTime( int arr[], int P[], int n)
{
vector< int > adj[n+1];
for ( int i = 0; i < n; i++) {
adj[arr[i]].push_back(P[i]);
}
vector< bool > visited(n+1);
int ans = 1;
for ( int i = 0; i < n; i++) {
if (!visited[i]) {
ans = lcm(ans, dfs(i, adj, visited));
}
}
return ans;
}
int main()
{
int arr[] = { 1, 2, 3 };
int P[] = { 3, 2, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << findMinTime(arr, P, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int lcm( int a, int b)
{
return (a * b) / (__gcd(a, b));
}
static int __gcd( int a, int b)
{
return b == 0 ? a:__gcd(b, a % b);
}
static int dfs( int src, Vector<Integer> adj[], boolean []visited)
{
visited[src] = true ;
int count = 1 ;
for ( int i = 0 ; i < adj[src].size(); i++)
if (!visited[adj[src].get(i)])
count += dfs(adj[src].get(i), adj, visited);
return count;
}
static int findMinTime( int arr[], int P[], int n)
{
Vector<Integer> []adj = new Vector[n + 1 ];
for ( int i = 0 ; i < n + 1 ; i++)
adj[i] = new Vector<Integer>();
for ( int i = 0 ; i < n; i++)
{
adj[arr[i]].add(P[i]);
}
boolean []visited = new boolean [n + 1 ];
int ans = 1 ;
for ( int i = 0 ; i < n; i++)
{
if (!visited[i])
{
ans = lcm(ans, dfs(i, adj, visited));
}
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 };
int P[] = { 3 , 2 , 1 };
int n = arr.length;
System.out.print(findMinTime(arr, P, n));
}
}
|
Python
import math
def lcm(a, b):
return (a * b) / / (math.gcd(a, b))
def dfs(src, adj, visited):
visited[src] = True
count = 1
if adj[src] ! = 0 :
for i in range ( len (adj[src])):
if ( not visited[adj[src][i]]):
count + = dfs(adj[src][i], adj, visited)
return count
def findMinTime(arr, P, n):
adj = [ 0 ] * (n + 1 )
for i in range (n):
if adj[arr[i]] = = 0 :
adj[arr[i]] = []
adj[arr[i]].append(P[i])
visited = [ 0 ] * (n + 1 )
ans = 1
for i in range (n):
if ( not visited[i]):
ans = lcm(ans, dfs(i, adj, visited))
return ans
arr = [ 1 , 2 , 3 ]
P = [ 3 , 2 , 1 ]
n = len (arr)
print (findMinTime(arr, P, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int lcm( int a, int b)
{
return (a * b) / (__gcd(a, b));
}
static int __gcd( int a, int b)
{
return b == 0 ? a:__gcd(b, a % b);
}
static int dfs( int src, List< int > []adj, bool []visited)
{
visited[src] = true ;
int count = 1;
for ( int i = 0; i < adj[src].Count; i++)
if (!visited[adj[src][i]])
count += dfs(adj[src][i], adj, visited);
return count;
}
static int findMinTime( int []arr, int []P, int n)
{
List< int > []adj = new List< int >[n + 1];
for ( int i = 0; i < n + 1; i++)
adj[i] = new List< int >();
for ( int i = 0; i < n; i++)
{
adj[arr[i]].Add(P[i]);
}
bool []visited = new bool [n + 1];
int ans = 1;
for ( int i = 0; i < n; i++)
{
if (!visited[i])
{
ans = lcm(ans, dfs(i, adj, visited));
}
}
return ans;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 3 };
int []P = { 3, 2, 1 };
int n = arr.Length;
Console.Write(findMinTime(arr, P, n));
}
}
|
Javascript
<script>
function lcm(a, b) {
return (a * b) / (__gcd(a, b));
}
function __gcd(a, b) {
return b == 0 ? a : __gcd(b, a % b);
}
function dfs(src, adj, visited) {
visited[src] = true ;
let count = 1;
for (let i = 0; i < adj[src].length; i++)
if (!visited[adj[src][i]])
count += dfs(adj[src][i], adj, visited);
return count;
}
function findMinTime(arr, P, n) {
let adj = new Array(n + 1);
for (let i = 0; i < n + 1; i++)
adj[i] = new Array();
for (let i = 0; i < n; i++) {
adj[arr[i]].push(P[i]);
}
let visited = new Array(n + 1);
let ans = 1;
for (let i = 0; i < n; i++) {
if (!visited[i]) {
ans = lcm(ans, dfs(i, adj, visited));
}
}
return ans;
}
let arr = [1, 2, 3];
let P = [3, 2, 1];
let n = arr.length;
document.write(findMinTime(arr, P, n));
</script>
|
Share your thoughts in the comments
Please Login to comment...