Minimum operation require to make first and last character same

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to minimum operation require 
// to make first and last character same
#include <bits/stdc++.h>
using namespace std;
  
const int MAX = INT_MAX;
  
// Recursive function call
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;
  
    // Decrement ending index only
    if(i >=s.size())
        return minOperation(s,i,j-1,count+1);
          
    // Increment starting index only
    else if(j<0)
        return minOperation(s,i+1,j,count+1);
      
    // Increment starting index and decrement index
    else
        return min(minOperation(s,i,j-1,count+1),minOperation(s,i+1,j,count+1));
  
  
}
  
// Driver code
int main() {
      
    string s = "bacdefghipalop";
      
    // Function call
    int ans = minOperation(s,0,s.size()-1,0);
      
    if(ans == MAX)
        cout<<-1;
    else
        cout<<ans;
      
    return 0;
}

chevron_right


Output:

4

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 tabulation method in terms of time complexity.

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find minimum operation require 
// to make first and last character same
#include <bits/stdc++.h>
using namespace std;
const int MAX = INT_MAX;
  
// To store the visited strings
map <string,int> m;
  
int Min = INT_MAX; 
  
// Function to find minimum operation require 
// to make first and last character same
int minOperation(string &s,int i,int j,int count)
{
    // Base conditions
    if((i>=s.size() && j<0) || (i == j))
        return MAX;
          
    // If answer found
    if(s[i] == s[j] || (count >= Min))
        return count;
  
    string str = to_string(i) + "|"+to_string(j);
      
    // If string is already visited
    if(m.find(str) == m.end())
    {
        // Decrement ending index only
        if(i >=s.size())
        m[str]= minOperation(s,i,j-1,count+1);
          
        // Increment starting index only
        else if(j<0)
        m[str]= minOperation(s,i+1,j,count+1);
          
        // Increment starting index and decrement index
        else
        m[str]= min(minOperation(s,i,j-1,count+1),minOperation(s,i+1,j,count+1));
    }
      
    // Store the minimum value
    if(m[str] < Min)
            Min = m[str];
    return m[str];
  
}
  
// Driver code
int main() 
{
    string s = "bacdefghipalop";
      
    // Function call
    int ans = minOperation(s,0,s.size()-1,0);
      
    if(ans == MAX)
        cout<<-1;
    else
        cout<<ans;
}

chevron_right


Output:

4

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 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.

Below is implementation of this approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find minimum operation 
// require to make first and last character same
#include <bits/stdc++.h>
using namespace std;
#define MAX 256
  
// Return the minimum operation require 
// to make string first and last character same.
int minimumOperation(string s)
{
    int n = s.length();
      
    // Store indexes of first occurrences of characters.
    vector<int> first_occ(MAX, -1); 
  
    // Initialize result
    int res = INT_MAX; 
  
    // Traverse through all characters
    for (int i=0; i<n; i++)
    {
        // Find first occurrence
        char x = s[i];
        if (first_occ[x] == -1)
        first_occ[x] = i;
  
        // Update result for subsequent occurrences
        else
        {
        int last_occ = (n-i-1);
        res = min(res, first_occ[x] + last_occ);
        }
    }
    return res;
}
  
// Driven Program
int main()
{
    string s = "bacdefghipalop";
    cout << minimumOperation(s) << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find minimum 
// operation require to make 
// first and last character same
  
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GFG{
  
static final int MAX=256;
  
// Return the minimum operation requires to 
// make string first and last character same.
static int minimumOperation(String s)
{
    int n = s.length();
      
    // Store indexes of first occurrences of characters.
    Vector<Integer> first_occ=new Vector<Integer>();
      
    //Initialize all the elements to -1
    for(int i=0;i<MAX;i++)
    first_occ.add(i,-1);
      
    // Initialize result
    int res = Integer.MAX_VALUE; 
  
    // Traverse through all characters
    for (int i=0; i<n; i++)
    {
        // Find first occurrence
        int x = (int)s.charAt(i);
        if (first_occ.elementAt(x) == -1)
        first_occ.set(x,i);
  
        // Update result for subsequent occurrences
        else
        {
        int last_occ = (n-i-1);
        res = Math.min(res, first_occ.get(x) + last_occ);
        }
    }
    return res;
}
  
// Driven Program
public static void main(String args[])
{
    String s = "bacdefghipalop";
    System.out.println(minimumOperation(s));
}
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find minimum operation 
# require to make first and last character same 
MAX = 256
  
# Return the minimum operation require to 
# make string first and last character same. 
def minimumOperation(s): 
  
    n = len(s) 
      
    # Store indexes of first 
    # occurrences of characters. 
    first_occ = [-1] * MAX
  
    # Initialize result 
    res = float('inf'
  
    # Traverse through all characters 
    for i in range(0, n): 
      
        # Find first occurrence 
        x = s[i] 
        if first_occ[ord(x)] == -1
            first_occ[ord(x)] =
  
        # Update result for subsequent occurrences 
        else:
            last_occ = n - i - 1
            res = min(res, first_occ[ord(x)] + last_occ) 
      
    return res 
  
# Driver Code
if __name__ == "__main__":
  
    s = "bacdefghipalop"
    print(minimumOperation(s)) 
      
# This code is contributed by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find minimum 
// operation require to make 
// first and last character same
using System;
using System.Collections.Generic; 
  
class GFG
{
  
static int MAX = 256;
  
// Return the minimum operation requires to 
// make string first and last character same.
static int minimumOperation(String s)
{
    int n = s.Length;
      
    // Store indexes of first occurrences of characters.
    List<int> first_occ = new List<int>();
      
    //Initialize all the elements to -1
    for(int i = 0; i < MAX; i++)
    first_occ.Insert(i,-1);
      
    // Initialize result
    int res = int.MaxValue; 
  
    // Traverse through all characters
    for (int i = 0; i < n; i++)
    {
        // Find first occurrence
        int x = (int)s[i];
        if (first_occ[x] == -1)
        first_occ.Insert(x,i);
  
        // Update result for subsequent occurrences
        else
        {
            int last_occ = (n - i - 1);
            res = Math.Min(res, first_occ[x] + last_occ);
        }
    }
    return res;
}
  
// Driver code
public static void Main(String []args)
{
    String s = "bacdefghipalop";
    Console.WriteLine(minimumOperation(s));
}
}
  
// This code contributed by Rajput-Ji

chevron_right


Output:

4

Time Complexity : O(n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.





Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.