Minimum operation require to make first and last character same
Last Updated :
01 Sep, 2022
Given a string S. You are allowed two types of operations:
- Remove a character from the front of the string.
- Remove a character from the end of the string.
The task is to find the minimum operations required to make the first and last character of the S same. In case, it is not possible, print “-1”.
Examples:
Input : S = "bacdefghipalop"
Output : 4
Remove 'b' from the front and remove 'p', 'o',
'l' from the end of the string S.
Input : S = "pqr"
Output : -1
Approaches:
Recursive: Call a recursive function passing four arguments string, starting index, ending index and count of the number of eliminations still now.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX = INT_MAX;
int minOperation(string &s, int i, int j, int count)
{
if ((i>=s.size() && j<0) || (i == j))
return MAX;
if (s[i] == s[j])
return count;
if (i >=s.size())
return minOperation(s,i,j-1,count+1);
else if (j<0)
return minOperation(s,i+1,j,count+1);
else
return min(minOperation(s,i,j-1,count+1),minOperation(s,i+1,j,count+1));
}
int main() {
string s = "bacdefghipalop" ;
int ans = minOperation(s,0,s.size()-1,0);
if (ans == MAX)
cout<<-1;
else
cout<<ans;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static final int MAX = Integer.MAX_VALUE;
static int minOperation(String s, int i, int j, int count)
{
if ((i >= s.length() && j < 0 ) || (i == j))
return MAX;
if (s.charAt(i) == s.charAt(j))
return count;
if (i >= s.length())
return minOperation(s, i, j - 1 , count + 1 );
else if (j < 0 )
return minOperation(s, i + 1 , j, count + 1 );
else
return Math.min(minOperation(s, i, j - 1 , count + 1 ),
minOperation(s, i + 1 , j, count + 1 ));
}
public static void main(String[] args)
{
String s = "bacdefghipalop" ;
int ans = minOperation(s, 0 , s.length() - 1 , 0 );
if (ans == MAX)
System.out.println(- 1 );
else
System.out.println(ans);
}
}
|
Python3
import sys
MAX = sys.maxsize
def minOperation(s, i, j, count):
if ((i > = len (s) and j < 0 ) or (i = = j)):
return MAX
if (s[i] = = s[j]):
return count
if (i > = len (s)):
return minOperation(s, i, j - 1 ,
count + 1 )
elif (j < 0 ):
return minOperation(s, i + 1 , j,
count + 1 )
else :
return min (minOperation(s, i, j - 1 ,
count + 1 ),
minOperation(s, i + 1 , j,
count + 1 ))
if __name__ = = '__main__' :
s = "bacdefghipalop"
ans = minOperation(s, 0 , len (s) - 1 , 0 )
if (ans = = MAX ):
print ( - 1 )
else :
print (ans)
|
C#
using System;
class GFG
{
static int MAX = Int32.MaxValue;
static int minOperation( string s, int i, int j, int count)
{
if ((i >= s.Length && j < 0) || (i == j))
return MAX;
if (s[i] == s[j])
return count;
if (i >= s.Length)
return minOperation(s, i, j - 1, count + 1);
else if (j < 0)
return minOperation(s, i + 1, j, count + 1);
else
return Math.Min(minOperation(s, i, j - 1, count + 1),
minOperation(s, i + 1, j, count + 1));
}
public static void Main()
{
string s = "bacdefghipalop" ;
int ans = minOperation(s, 0, s.Length - 1, 0);
if (ans == MAX)
Console.Write(-1);
else
Console.Write(ans);
}
}
|
Javascript
<script>
var MAX = 1000000000;
function minOperation( s,i,j,count)
{
if ((i>=s.length && j<0) || (i == j))
return MAX;
if (s[i] == s[j])
return count;
if (i >=s.length)
return minOperation(s,i,j-1,count+1);
else if (j<0)
return minOperation(s,i+1,j,count+1);
else
return Math.min(minOperation(s,i,j-1,count+1),
minOperation(s,i+1,j,count+1));
}
var s = "bacdefghipalop" ;
var ans = minOperation(s,0,s.length-1,0);
if (ans == MAX)
document.write( -1);
else
document.write( ans);
</script>
|
Dynamic Programming: The idea is to prevent making further recursive calls for count>= Min once we found the Min during every recursive call. It saves a lot of time and is almost comparable to the tabulation method in terms of time complexity.
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
const int MAX = INT_MAX;
map <string, int > m;
int Min = INT_MAX;
int minOperation(string &s, int i, int j, int count)
{
if ((i>=s.size() && j<0) || (i == j))
return MAX;
if (s[i] == s[j] || (count >= Min))
return count;
string str = to_string(i) + "|" +to_string(j);
if (m.find(str) == m.end())
{
if (i >=s.size())
m[str]= minOperation(s,i,j-1,count+1);
else if (j<0)
m[str]= minOperation(s,i+1,j,count+1);
else
m[str]= min(minOperation(s,i,j-1,count+1),minOperation(s,i+1,j,count+1));
}
if (m[str] < Min)
Min = m[str];
return m[str];
}
int main()
{
string s = "bacdefghipalop" ;
int ans = minOperation(s,0,s.size()-1,0);
if (ans == MAX)
cout<<-1;
else
cout<<ans;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int MAX = Integer.MAX_VALUE;
static HashMap<String, Integer> m = new HashMap<>();
static int Min = Integer.MAX_VALUE;
static int minOperation(String s, int i, int j, int count)
{
if ((i >= s.length() && j < 0 )|| (i == j))
{
return MAX;
}
if (s.charAt(i) == s.charAt(j) || (count >= Min))
{
return count;
}
String str = String.valueOf(i) + "|" + String.valueOf(j);
if (!m.containsKey(str))
{
if (i >= s.length())
{
m.put(str,minOperation(s, i, j - 1 , count + 1 ));
}
else if (j < 0 )
{
m.put(str,minOperation(s, i + 1 , j, count + 1 ));
}
else
{
m.put(str,Math.min(minOperation(s, i, j - 1 , count + 1 ), minOperation(s, i + 1 , j, count + 1 )));
}
}
if (m.get(str) < Min)
{
Min = m.get(str);
}
return m.get(str);
}
public static void main (String[] args)
{
String s = "bacdefghipalop" ;
int ans=minOperation(s, 0 , s.length() - 1 , 0 );
if (ans == MAX)
{
System.out.println(- 1 );
}
else
{
System.out.println(ans);
}
}
}
|
Python3
import sys
MAX = sys.maxsize
m = {}
Min = sys.maxsize
def minOperation(s, i, j, count):
global Min , MAX
if ((i > = len (s) and j < 0 ) or (i = = j)):
return MAX
if (s[i] = = s[j] or count > = Min ):
return count
Str = str (i) + "|" + str (j)
if Str not in m:
if (i > = len (s)):
m[ Str ] = minOperation(s, i, j - 1 , count + 1 )
elif (j < 0 ):
m[ Str ] = minOperation(s, i + 1 , j, count + 1 )
else :
m[ Str ] = min (minOperation(s, i, j - 1 , count + 1 ), minOperation(s, i + 1 , j, count + 1 ))
if (m[ Str ] < Min ):
Min = m[ Str ]
return m[ Str ]
s = "bacdefghipalop"
ans = minOperation(s, 0 , len (s) - 1 , 0 )
if (ans = = MAX ):
print ( - 1 )
else :
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = Int32.MaxValue;
static Dictionary< string , int > m = new Dictionary< string , int >();
static int Min = Int32.MaxValue;
static int minOperation( string s, int i, int j, int count)
{
if ((i >= s.Length && j < 0)|| (i == j))
{
return MAX;
}
if (s[i] == s[j] || (count >= Min))
{
return count;
}
string str = i.ToString() + "|" + j.ToString();
if (!m.ContainsKey(str))
{
if (i >= s.Length)
{
m[str] = minOperation(s, i, j - 1, count + 1);
}
else if (j < 0)
{
m[str] = minOperation(s, i + 1, j, count + 1);
}
else
{
m[str] = Math.Min(minOperation(s, i, j - 1, count + 1), minOperation(s, i + 1, j, count + 1));
}
}
if (m[str] < Min)
{
Min = m[str];
}
return m[str];
}
static void Main()
{
string s = "bacdefghipalop" ;
int ans=minOperation(s, 0, s.Length - 1, 0);
if (ans == MAX)
{
Console.WriteLine(-1);
}
else
{
Console.WriteLine(ans);
}
}
}
|
Javascript
<script>
let MAX = Number.MAX_VALUE;
let m = new Map();
let Min = Number.MAX_VALUE;
function minOperation(s, i, j, count)
{
if ((i >= s.length && j < 0)|| (i == j))
{
return MAX;
}
if (s[i] == s[j] || (count >= Min))
{
return count;
}
let str = (i).toString() + "|" + (j).toString();
if (!m.has(str))
{
if (i >= s.length)
{
m.set(str,minOperation(s, i, j - 1, count + 1));
}
else if (j < 0)
{
m.set(str,minOperation(s, i + 1, j, count + 1));
}
else
{
m.set(str,Math.min(minOperation(s, i, j - 1, count + 1), minOperation(s, i + 1, j, count + 1)));
}
}
if (m.get(str) < Min)
{
Min = m.get(str);
}
return m.get(str);
}
let s = "bacdefghipalop" ;
let ans=minOperation(s, 0, s.length - 1, 0);
if (ans == MAX)
{
document.write(-1);
}
else
{
document.write(ans);
}
</script>
|
Dynamic programming with Tabulation:
The idea is to find the first and last occurrences of each character in the string. The total amount of operations needed will be simply “number of operations needed to remove the first occurrence” plus “number of operations needed to remove the last occurrence”. So, do this for each character in the string and the answer will be a minimum of such operations performed on each character.
For example, S = “zabcdefghaabbbb”, calculate the operations required to have character ‘a’ at both the front and the end, meaning to say the string “a….a”. For the minimum number of operations, we will form the string “abcdefghaa” i.e we will remove one character ‘z’ from front and 4 characters ‘bbbb’ from back. Hence total 5 operations will be required.
So, apply the above algorithm for each character and hence we can then find the minimum of those operations.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define MAX 256
int minimumOperation(string s)
{
int n = s.length();
vector< int > first_occ(MAX, -1);
int res = INT_MAX;
for ( int i=0; i<n; i++)
{
char x = s[i];
if (first_occ[x] == -1)
first_occ[x] = i;
else
{
int last_occ = (n-i-1);
res = min(res, first_occ[x] + last_occ);
}
}
return res;
}
int main()
{
string s = "bacdefghipalop" ;
cout << minimumOperation(s) << endl;
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
static final int MAX= 256 ;
static int minimumOperation(String s)
{
int n = s.length();
Vector<Integer> first_occ= new Vector<Integer>();
for ( int i= 0 ;i<MAX;i++)
first_occ.add(i,- 1 );
int res = Integer.MAX_VALUE;
for ( int i= 0 ; i<n; i++)
{
int x = ( int )s.charAt(i);
if (first_occ.elementAt(x) == - 1 )
first_occ.set(x,i);
else
{
int last_occ = (n-i- 1 );
res = Math.min(res, first_occ.get(x) + last_occ);
}
}
return res;
}
public static void main(String args[])
{
String s = "bacdefghipalop" ;
System.out.println(minimumOperation(s));
}
}
|
Python3
MAX = 256
def minimumOperation(s):
n = len (s)
first_occ = [ - 1 ] * MAX
res = float ( 'inf' )
for i in range ( 0 , n):
x = s[i]
if first_occ[ ord (x)] = = - 1 :
first_occ[ ord (x)] = i
else :
last_occ = n - i - 1
res = min (res, first_occ[ ord (x)] + last_occ)
return res
if __name__ = = "__main__" :
s = "bacdefghipalop"
print (minimumOperation(s))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = 256;
static int minimumOperation(String s)
{
int n = s.Length;
List< int > first_occ = new List< int >();
for ( int i = 0; i < MAX; i++)
first_occ.Insert(i,-1);
int res = int .MaxValue;
for ( int i = 0; i < n; i++)
{
int x = ( int )s[i];
if (first_occ[x] == -1)
first_occ.Insert(x,i);
else
{
int last_occ = (n - i - 1);
res = Math.Min(res, first_occ[x] + last_occ);
}
}
return res;
}
public static void Main(String []args)
{
String s = "bacdefghipalop" ;
Console.WriteLine(minimumOperation(s));
}
}
|
Javascript
<script>
const MAX = 256
function minimumOperation(s)
{
let n = s.length;
let first_occ = new Array(MAX).fill(-1);
let res = Number.MAX_VALUE;
for (let i=0; i<n; i++)
{
let x = s.charCodeAt(i);
if (first_occ[x] == -1)
first_occ[x] = i;
else
{
let last_occ = (n-i-1);
res = Math.min(res, first_occ[x] + last_occ);
}
}
return res;
}
let s = "bacdefghipalop" ;
document.write(minimumOperation(s));
</script>
|
Time Complexity: O(n)
Share your thoughts in the comments
Please Login to comment...