Minimize operations to restore original string by permutation
Last Updated :
05 Mar, 2024
Given a string S and permutation P, both of length N. In one operation you can change the position of each and every character of the string from S[i] to S[P[i]]. Determine the minimum number of operations to restore the original string.
Examples:
Input: S = "ababa", P = [3, 4, 5, 2, 1]
Output: 1
Explanation: After first operation on S, we will get S' = "ababa". Since S' = S, so min number of operations = 1.
Input: S="ababa", P = [2, 1, 4, 5, 3]
Output: 6
Explanation:
- After first operation on S, we will get S' = "babaa".
- After second operation on S, we will get S'' = "abaab".
- After third operation on S, we will get S''' = "baaba".
- After fourth operation on S, we will get S'''' = "abbaa".
- After fifth operation on S, we will get S''''' = "baaab".
- After sixth operation on S, we will get S'''''' = "ababa". Since S'''''' = S, so min number of operations= 6.
Approach: To solve the problem, follow the below idea:
If we observe carefully, then each character of the original string S will reach back to its original position after some operations. So, if we keep on applying the operation continuously then each of the character will move in a cycle across the string S. So, the approach is to identify cycles in a permutation, represented by the vector P, and compute the lengths of these cycles, and calculates their Least Common Multiple (LCM) to determine the final result. The process is based on traversing the permutation indices and forming cycles, leveraging the cyclic property of the permutation.
Intuition:
- Each cycle is formed by following the permutation until a previously visited index is reached.
- The length of a cycle is found by searching for the starting position of the substring in the doubled string.
- The LCM is used to accumulate the lengths of cycles for different starting positions, ensuring that the final result represents the shortest repeating cycle for the entire permutation.
It finds the length of the shortest repeating cycle in a given permutation of a string by leveraging the LCM property of cycle lengths.
Step-by-step algorithm:
- The main loop iterates through the indices i from 1 to N.
- If the index i is not visited (!used[i]), it starts a cycle.
- Inside the cycle, it creates a string t by traversing the permutation until it reaches a previously visited index.
- For each cycle, it calculates the length of the cycle (cyc) by finding the position of the first occurrence of the substring t in the concatenated string t + t starting from position 1.
- The answer (ans) is updated by taking the least common multiple (LCM) of the current answer and the length of the cycle (cyc).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// Function to calculate the least common multiple (LCM)
long long lcm(long long a, long long b)
{
return (a * b) / __gcd(a, b);
}
int main()
{
// Driver code
string S = "ababa";
long long N = 5;
vector<ll> P = {2, 1, 4, 5, 3 };
// 0-based indexing
for(int i = 0; i < N; i++) {
P[i] -= 1;
}
// Array to mark visited indices during iteration
vector<ll> used(N + 1);
// Initialize the answer variable to 1
ll ans = 1;
// Iterate through each index in the permutation
for (int i = 1; i <= N; i++)
// If the index is not visited,start a new cycle
if (!used[i]) {
string t;
// Generate a cycle by following the permutation
// until a previously visited index is
// encountered
for (ll j = i; !used[j]; j = P[j]) {
// Mark the index as visited
used[j] = 1;
// Build the cycle substring
t += S[j - 1];
}
// Calculate the length of the cycle by finding
// the starting position of the substring in the
// doubled string
ll cyc = (t + t).find(t, 1);
// Update the answer by taking the LCM with the
// current cycle length
ans = lcm(ans, cyc);
}
cout << ans;
}
Java
// Java Implementation
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// Example usage
String S = "ababa";
List<Integer> P = new ArrayList<>();
P.add(2);
P.add(1);
P.add(4);
P.add(5);
P.add(3);
System.out.println(minOperations(S, P)); // Output: 6
}
// Function to calculate the minimum number of operations required
// to form a cycle using the given permutation
public static int minOperations(String S, List<Integer> P) {
int N = S.length();
List<Boolean> visited = new ArrayList<>(N + 1);
// Initialize the visited array with false
for (int i = 0; i <= N; i++) {
visited.add(false);
}
int result = 1; // Initialize the result variable to 1
// Iterate through each index in the permutation
for (int i = 1; i <= N; i++) {
// If the index is not visited, start a new cycle
if (!visited.get(i)) {
int cycleLength = 0;
int j = i;
// Generate a cycle by following the permutation
// until a previously visited index is encountered
while (!visited.get(j)) {
visited.set(j, true);
j = P.get(j - 1);
cycleLength++;
}
// Update the result by taking the LCM with the
// current cycle length
result = lcm(result, cycleLength);
}
}
return result;
}
// Function to calculate the greatest common divisor (GCD)
public static int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// Function to calculate the least common multiple (LCM)
public static int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
}
//This code is contributed by Tapesh(tapeshdu420)
C#
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Example usage
string S = "ababa";
List<int> P = new List<int> { 2, 1, 4, 5, 3 };
Console.WriteLine(MinOperations(S, P)); // Output: 6
}
static int MinOperations(string S, List<int> P)
{
int N = S.Length;
List<bool> visited = new List<bool>(new bool[N + 1]);
int result = 1;
for (int i = 1; i <= N; i++)
{
if (!visited[i])
{
int cycleLength = 0;
int j = i;
while (!visited[j])
{
visited[j] = true;
j = P[j - 1];
cycleLength++;
}
result = LCM(result, cycleLength);
}
}
return result;
}
static int GCD(int a, int b)
{
while (b != 0)
{
int temp = b;
b = a % b;
a = temp;
}
return a;
}
static int LCM(int a, int b)
{
return (a * b) / GCD(a, b);
}
}
JavaScript
// Function to calculate the greatest common divisor (GCD)
function gcd(a, b) {
return b === 0 ? a : gcd(b, a % b);
}
// Function to calculate the least common multiple (LCM)
function lcm(a, b) {
return (a * b) / gcd(a, b);
}
// Driver code
const S = "ababa";
const N = 5;
const P = [2, 1, 4, 5, 3].map(x => x - 1); // Convert to 0-based indexing
// Array to mark visited indices during iteration
const used = new Array(N + 1).fill(0);
// Initialize the answer variable to 1
let ans = 1;
// Iterate through each index in the permutation
for (let i = 0; i < N; i++) {
// If the index is not visited, start a new cycle
if (!used[i]) {
let t = "";
// Generate a cycle by following the permutation
// until a previously visited index is encountered
for (let j = i; !used[j]; j = P[j]) {
// Mark the index as visited
used[j] = 1;
// Build the cycle substring
t += S[j];
}
// Calculate the length of the cycle by finding
// the starting position of the substring in the
// doubled string
const cyc = t.length;
// Update the answer by taking the LCM with the
// current cycle length
ans = lcm(ans, cyc);
}
}
console.log(ans);
//This code is contributed by Aman.
Python3
# Python Implementation
def min_operations(S, P):
N = len(S)
visited = [False] * (N + 1)
result = 1 # Initialize the result variable to 1
# Iterate through each index in the permutation
for i in range(1, N + 1):
# If the index is not visited, start a new cycle
if not visited[i]:
cycle_length = 0
j = i
# Generate a cycle by following the permutation
# until a previously visited index is encountered
while not visited[j]:
visited[j] = True
j = P[j - 1]
cycle_length += 1
# Update the result by taking the LCM with the
# current cycle length
result = lcm(result, cycle_length)
return result
# Function to calculate the greatest common divisor (GCD)
def gcd(a, b):
while b != 0:
temp = b
b = a % b
a = temp
return a
# Function to calculate the least common multiple (LCM)
def lcm(a, b):
return (a * b) // gcd(a, b)
# Example usage
if __name__ == "__main__":
# Example usage
S = "ababa"
P = [2, 1, 4, 5, 3]
print(min_operations(S, P)) # Output: 6
#this code is contributed by Adarsh
Time Complexity: O(N), where N is the length of the permutation.
Auxiliary Space: O(N).
Similar Reads
Minimizing Operations to Rewrite a String Given a string S, you have to write the same given string using two operations, the task is to find the minimum number of operations to write it. You can only write a sequence of the same character each time.You can choose any substring and overwrite the existing characters with single new character
7 min read
Minimize count of given operations required to make two given strings permutations of each other Given two strings str1 and str2, the task is to count the minimum number of operations of the following three types on one of the two strings that are required to make str1 and str2 permutations of each other: Insert a character into the string.Remove a character from the string.Replace a character
13 min read
All permutations of a string using iteration A permutation, also called an âarrangement numberâ or âorderâ, is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation ( Source: Mathword ) Below are the permutations of string ABC. ABC ACB BAC BCA CBA CAB We hav
4 min read
Distinct permutations of the string | Set 2 Given a string s, the task is to return all unique permutations of a given string in lexicographically sorted order.Note: A permutation is the rearrangement of all the elements of a string. Examples:Input: s = "ABC"Output: "ABC", "ACB", "BAC", "BCA", "CBA", "CAB"Input: s = "XY"Output: "XY", "YX"Inpu
6 min read
Minimize the size of the string formed by performing following operation Given array of strings arr[] of size N. Task for this problem is minimize the size of N'th string formed by performing concatenation operation. If we concat string a and string b to get concat(a, b) then while concatenation if the last character of a is same as first character of b then delete eithe
15+ min read