Minimum operations to transform given string to another by moving characters to front or end
Last Updated :
06 Apr, 2023
Given two Strings S and T of length N consisting of lowercase alphabets, which are permutations of each other, the task is to print the minimum number of operations to convert S to T. In one operation, pick any character of the string S and move it either to the start or end of the string S.
Examples:
Input: S = "abcde", T = "edacb"
Output: 3
Explanation:
We can convert S to T in 3 moves:
1. move 'd' to start: "dabce"
2. move 'e' to start: "edabc"
3. move 'b' to end: "edacb"
Input: S = "dcdb", T = "ddbc"
Output: 1
Explanation:
Move 'c' to end
Naive Approach: The naive approach is to try all possibilities of swapping a character. One can put some character to the front, to the end, or can leave it in the same position. The above three operations can be solved using recursion and print the minimum number of steps required after all the steps.
Time Complexity: O(3N), where N is the length of the given string.
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to observe that after moving the characters of the string S, the unchanged characters come together to form a contiguous substring in T. So, if we can maximize the length of this subsequence, then the count of operations to convert string S to T is:
N - length of the longest contiguous substring of T that is a subsequence of S
Therefore, to find the length of the longest contiguous substring of T that is a subsequence of string S, find the longest common subsequence of S and T. Let dp[][] stores the length of the longest contiguous substring of T that is a subsequence of string S, . Now dp[i][j] will store the length of the longest suffix of T[0, ..., j] that is also a subsequence of S[0, ..., i]. The recurrence relation is given by:
- If i is greater than 0, dp[i][j] = max(dp[i-1][j], dp[i][j]).
- If S[i] is equals to T[i] then, dp[i][j] = 1 + dp[i-1][j-1].
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
int dp[1010][1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
int solve(string s, string t)
{
int n = s.size();
// r = maximum value over all
// dp[i][j] computed so far
int r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = 0;
if (i > 0) {
dp[i][j] = max(dp[i - 1][j],
dp[i][j]);
}
if (s[i] == t[j]) {
int ans = 1;
if (i > 0 && j > 0) {
ans = 1 + dp[i - 1][j - 1];
}
// Update the maximum length
dp[i][j] = max(dp[i][j], ans);
r = max(r, dp[i][j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
int main()
{
// Given string s, t
string s = "abcde";
string t = "edacb";
// Function Call
cout << solve(s, t);
return 0;
}
Java
// Java program for the above approach
class GFG{
static int[][] dp = new int[1010][1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert String s to t
static int solve(String s, String t)
{
int n = s.length();
// r = maximum value over all
// dp[i][j] computed so far
int r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i][j] = 0;
if (i > 0)
{
dp[i][j] = Math.max(dp[i - 1][j],
dp[i][j]);
}
if (s.charAt(i) == t.charAt(j))
{
int ans = 1;
if (i > 0 && j > 0)
{
ans = 1 + dp[i - 1][j - 1];
}
// Update the maximum length
dp[i][j] = Math.max(dp[i][j], ans);
r = Math.max(r, dp[i][j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void main(String[] args)
{
// Given String s, t
String s = "abcde";
String t = "edacb";
// Function Call
System.out.print(solve(s, t));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
dp = [[0] * 1010] * 1010
# Function that finds the minimum number
# of steps to find the minimum characters
# must be moved to convert string s to t
def solve(s, t):
n = len(s)
# r = maximum value over all
# dp[i][j] computed so far
r = 0
# dp[i][j] stores the longest
# contiguous suffix of T[0..j]
# that is subsequence of S[0..i]
for j in range(0, n):
for i in range(0, n):
dp[i][j] = 0
if (i > 0):
dp[i][j] = max(dp[i - 1][j],
dp[i][j])
if (s[i] == t[j]):
ans = 1
if (i > 0 and j > 0):
ans = 1 + dp[i - 1][j - 1]
# Update the maximum length
dp[i][j] = max(dp[i][j], ans)
r = max(r, dp[i][j])
# Return the resulting length
return (n - r)
# Driver Code
# Given string s, t
s = "abcde"
t = "edacb"
# Function call
print(solve(s, t))
# This code is contributed by code_hunt
C#
// C# program for the above approach
using System;
class GFG{
static int[, ] dp = new int[1010, 1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert String s to t
static int solve(String s, String t)
{
int n = s.Length;
// r = maximum value over all
// dp[i, j] computed so far
int r = 0;
// dp[i, j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i, j] = 0;
if (i > 0)
{
dp[i, j] = Math.Max(dp[i - 1, j],
dp[i, j]);
}
if (s[i] == t[j])
{
int ans = 1;
if (i > 0 && j > 0)
{
ans = 1 + dp[i - 1, j - 1];
}
// Update the maximum length
dp[i, j] = Math.Max(dp[i, j], ans);
r = Math.Max(r, dp[i, j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void Main(String[] args)
{
// Given String s, t
String s = "abcde";
String t = "edacb";
// Function Call
Console.Write(solve(s, t));
}
}
// This code is contributed by shikhasingrajput
JavaScript
<script>
// Javascript program for the above approach
var dp = Array.from(Array(1010), ()=> Array(1010));
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
function solve(s, t)
{
var n = s.length;
// r = maximum value over all
// dp[i][j] computed so far
var r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
dp[i][j] = 0;
if (i > 0) {
dp[i][j] = Math.max(dp[i - 1][j],
dp[i][j]);
}
if (s[i] == t[j]) {
var ans = 1;
if (i > 0 && j > 0) {
ans = 1 + dp[i - 1][j - 1];
}
// Update the maximum length
dp[i][j] = Math.max(dp[i][j], ans);
r = Math.max(r, dp[i][j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
// Given string s, t
var s = "abcde";
var t = "edacb";
// Function Call
document.write( solve(s, t));
</script>
Time Complexity: O(N2), where N is the length of the given string
Auxiliary Space: O(N2)
Efficient approach : Space optimization using 2 vectors
In this approach we use two vectors because in previous approach we can see that dp[i][j] is only dependent on the current row and previous row of dp.
dp[i][j] = max(dp[i - 1][j], dp[i][j]);
Implementation Steps :
- Made 2 vectors says curr and prev that use to keep track of values of current and previous row of matrix respectively.
- Now change dp[i] to curr and dp[i-1] to prev in previous approach.
- After every iteration of outer loop store all values of curr to prev and move to the next iterations
Implementation :
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
int solve(string s, string t)
{
int n = s.size();
// vector made to track only 2 rows of 2d dp
vector<int>prev(n+1);
vector<int>curr(n+1);
// r = maximum value over all
// dp[i][j] computed so far
int r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
curr[j] = 0;
if (i > 0) {
curr[j] = max(prev[j], curr[j]);
}
if (s[i] == t[j]) {
int ans = 1;
if (i > 0 && j > 0) {
ans = 1 + prev[j - 1];
}
// Update the maximum length
curr[j] = max(curr[j], ans);
r = max(r, curr[j]);
}
}
// store current row in previous row and do another iterations
prev = curr;
}
// Return the resulting length
return (n - r);
}
// Driver Code
int main()
{
// Given string s, t
string s = "abcde";
string t = "edacb";
// Function Call
cout << solve(s, t);
return 0;
}
// this code is contributed by bhardwajji
Java
// Java program for the above approach
import java.util.*;
public class Main {
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
static int solve(String s, String t) {
int n = s.length();
int[] prev = new int[n+1];
int[] curr = new int[n+1];
int r = 0;
// dp[i][j] stores the longest contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
curr[j] = 0;
if (i > 0) {
curr[j] = Math.max(prev[j], curr[j]);
}
if (s.charAt(i) == t.charAt(j)) {
int ans = 1;
if (i > 0 && j > 0) {
ans = 1 + prev[j - 1];
}
curr[j] = Math.max(curr[j], ans);
r = Math.max(r, curr[j]);
}
}
// store current row in previous row and do another iterations
prev = curr.clone();
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void main(String[] args) {
// Given string s, t
String s = "abcde";
String t = "edacb";
// Function Call
System.out.println(solve(s, t));
}
}
// Contributed by sdeadityasharma
Python3
# Function that finds the minimum number
# of steps to find the minimum characters
# must be moved to convert string s to t
def solve(s, t):
n = len(s)
# list made to track only 2 rows of 2d dp
prev = [0] * (n + 1)
curr = [0] * (n + 1)
# r = maximum value over all
# dp[i][j] computed so far
r = 0
# dp[i][j] stores the longest
# contiguous suffix of T[0..j]
# that is subsequence of S[0..i]
for i in range(n):
for j in range(n):
curr[j] = 0
if i > 0:
curr[j] = max(prev[j], curr[j])
if s[i] == t[j]:
ans = 1
if i > 0 and j > 0:
ans = 1 + prev[j - 1]
# Update the maximum length
curr[j] = max(curr[j], ans)
r = max(r, curr[j])
# store current row in previous row and do another iterations
prev = curr[:]
# Return the resulting length
return (n - r)
# Driver Code
if __name__ == '__main__':
# Given string s, t
s = "abcde"
t = "edacb"
# Function Call
print(solve(s, t))
C#
using System;
public class MainClass {
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
static int Solve(string s, string t)
{
int n = s.Length;
int[] prev = new int[n + 1];
int[] curr = new int[n + 1];
int r = 0;
// dp[i][j] stores the longest contiguous suffix of
// T[0..j] that is subsequence of S[0..i]
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
curr[j] = 0;
if (i > 0) {
curr[j] = Math.Max(prev[j], curr[j]);
}
if (s[i] == t[j]) {
int ans = 1;
if (i > 0 && j > 0) {
ans = 1 + prev[j - 1];
}
curr[j] = Math.Max(curr[j], ans);
r = Math.Max(r, curr[j]);
}
}
// store current row in previous row and do
// another iterations
prev = (int[])curr.Clone();
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void Main(string[] args)
{
// Given string s, t
string s = "abcde";
string t = "edacb";
// Function Call
Console.WriteLine(Solve(s, t));
}
}
// This code is contributed by user_dtewbxkn77n
JavaScript
// Javascript program for the above approach
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
function solve(s, t) {
const n = s.length;
let prev = new Array(n + 1).fill(0);
let curr = new Array(n + 1).fill(0);
let r = 0;
// dp[i][j] stores the longest contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
curr[j] = 0;
if (i > 0) {
curr[j] = Math.max(prev[j], curr[j]);
}
if (s.charAt(i) == t.charAt(j)) {
let ans = 1;
if (i > 0 && j > 0) {
ans = 1 + prev[j - 1];
}
curr[j] = Math.max(curr[j], ans);
r = Math.max(r, curr[j]);
}
}
// store current row in previous row and do another iterations
prev = curr.slice();
}
// Return the resulting length
return n - r;
}
// Driver Code
const s = "abcde";
const t = "edacb";
// Function Call
console.log(solve(s, t));
Time Complexity: O(N2), where N is the length of the given string
Auxiliary Space: O(N) only use 1d vector not 2d matrix to store values.
Note: The above naive approach is efficient for smaller strings whereas, the above efficient approach is efficient for larger strings.
Similar Reads
Minimum cost to convert one given string to another using swap, insert or delete operations
Given two strings A and B of length N and M respectively, the task is to find the minimum cost to convert string A to B using the following operations: A character of string A can be swapped from another character of the same string. Cost = 0.A character can be deleted from string B or can be insert
6 min read
Transform One String to Another using Minimum Number of Given Operation
Given two strings A and B, the task is to convert A to B if possible. The only operation allowed is to put any character from A and insert it at front. Find if it's possible to convert the string. If yes, then output minimum no. of operations required for transformation.Examples: Input: A = "ABD", B
15+ min read
Minimum number of Appends of X or Y characters from the end to the front required to obtain given string
Given a string S and two positive integers X and Y, the task is to find the minimum number of operations required to obtain the original string. In each operation, append X or Y characters from the end of the string to the front of the string respectively in each operation. Examples: Input: S = "Gee
8 min read
Minimum number of given operations required to convert a string to another string
Given two strings S and T of equal length. Both strings contain only the characters '0' and '1'. The task is to find the minimum number of operations to convert string S to T. There are 2 types of operations allowed on string S: Swap any two characters of the string.Replace a '0' with a '1' or vice
14 min read
Check if it is possible to transform one string to another
Given two strings s1 and s2(all letters in uppercase). Check if it is possible to convert s1 to s2 by performing following operations. Make some lowercase letters uppercase. Delete all the lowercase letters. Examples: Input : s1 = daBcd s2 = ABC Output : yes Explanation : daBcd -> dABCd -> ABC
7 min read
Transform string A into B by deleting characters from ends and reinserting at any position
Given two strings A and B that are anagrams of each other, the task is to convert A to B if possible in minimum number of operations. An operation is defined as removing either the first or the last character in A and inserting it back anywhere in the string. Examples: Input: A = "edacb", B = "abcde
13 min read
Minimize operations to make one string contain only characters from other string
Given two strings S1 and S2 containing only lower case English alphabets, the task is to minimize the number of operations required to make S1 contain only characters from S2 where in each operation any character of S1 can be converted to any other letter and the cost of the operation will be differ
9 min read
Count characters to be shifted from the start or end of a string to obtain another string
Given two strings A and B where string A is an anagram of string B. In one operation, remove the first or the last character of the string A and insert at any position in A. The task is to find the minimum number of such operations required to be performed to convert string A into string B. Examples
6 min read
Minimum cost to convert str1 to str2 with the given operations
Given two strings of equal lengths str1 and str2 consist of characters 'a' and 'b' only. The following operations can be performed on str1: Any character can be changed from 'a' to 'b' or from 'b' to 'a' with 1 unit cost.Any two characters str1[i] and str1[j] can be swapped with cost |i - j|. The ta
6 min read
Minimum number of deletions and insertions to transform one string into another
Given two strings s1 and s2. The task is to remove/delete and insert the minimum number of characters from s1 to transform it into s2. It could be possible that the same character needs to be removed/deleted from one point of s1 and inserted at another point.Example 1: Input: s1 = "heap", s2 = "pea"
15+ min read