Open In App

Minimum count of prefixes and suffixes of a string required to form given string

Last Updated : 19 Sep, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings str1 and str2, the task is to find the minimum number of prefixes and suffixes of str2 required to form the string str1. If the task is not possible, return “-1”.

Example: 

Input: str1 = “HELLOWORLD”, str2 = “OWORLDHELL”
Output: 2
Explanation: The above string can be formed as “HELL” + “OWORLD” which are suffix and prefix of the string str2

Input: str = “GEEKSFORGEEKS”, wrd = “SFORGEEK”
Output: 3
Explanation: “GEEK” + “SFORGEEK” + “S”  

 

Approach: The above problem can be solved using dynamic programming. Follow the steps below to solve the problem:

  • Initialize an array dp where the ith element arr[i] will store the minimum concatenation required to form a string up to prefix index i
  • Initialize dp[0] = 0 and other values of the dp array to -1
  • Initialize a HashSet set
  • Iterate the string str1 from left to right and at every index i:
    • Add the substring from index 0 to current index i into the HashSet set
  • Iterate the string str1 from right to left and at every index i:
    • Add the substring from index i to the end index into the HashSet set
  • Check for all the substrings in the string str1 and update the dp, accordingly
  • The final answer will be stored in dp[N], where N is the length of string str1

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum number of
// concatenation of prefix and suffix
// of str2 to make str1
int partCount(string str1, string str2)
{
 
    // Initialize a set
    unordered_set<string> set;
 
    // Initialize a temporary string
    string temp = "";
 
    int l1 = str1.length(), l2 = str2.length();
 
    // Iterate the string str2
    // from left to right
    for (int i = 0; i < l2; i++) {
 
        // Add current character
        // to string temp
        temp += str2[i];
 
        // Insert the prefix into hashset
        set.insert(temp);
    }
 
    // Re-initialize temp string
    // to empty string
    temp = "";
 
    // Iterate the string in reverse direction
    for (int i = l2 - 1; i >= 0; i--) {
 
        // Add current character to temp
        temp += str2[i];
 
        // Reverse the string temp
        reverse(temp.begin(), temp.end());
 
        // Insert the suffix into the hashset
        set.insert(temp);
 
        // Reverse the string temp again
        reverse(temp.begin(), temp.end());
    }
 
    // Initialize dp array to store the answer
    int dp[str1.length() + 1];
 
    memset(dp, -1, sizeof(dp));
    dp[0] = 0;
 
    // Check for all substrings starting
    // and ending at every indices
    for (int i = 0; i < l1; i++) {
        for (int j = 1; j <= l1 - i; j++) {
 
            // HashSet contains the substring
            if (set.count(str1.substr(i, j))) {
 
                if (dp[i] == -1) {
                    continue;
                }
                if (dp[i + j] == -1) {
                    dp[i + j] = dp[i] + 1;
                }
                else {
 
                    // Minimum of dp[i + j] and
                    // dp[i] + 1 will be stored
                    dp[i + j]
                        = min(dp[i + j], dp[i] + 1);
                }
            }
        }
    }
 
    // Return the answer
    return dp[str1.size()];
}
 
// Driver Code
int main()
{
    string str = "GEEKSFORGEEKS",
           wrd = "SFORGEEK";
 
    // Print the string
    cout << partCount(str, wrd);
}


Java




// Java implementation for the above approach
import java.util.Arrays;
import java.util.HashSet;
 
class GFG {
 
    // Function to find minimum number of
    // concatenation of prefix and suffix
    // of str2 to make str1
    public static int partCount(String str1, String str2) {
 
        // Initialize a set
        HashSet<String> set = new HashSet<String>();
 
        // Initialize a temporary string
        String temp = "";
 
        int l1 = str1.length(), l2 = str2.length();
 
        // Iterate the string str2
        // from left to right
        for (int i = 0; i < l2; i++) {
 
            // Add current character
            // to string temp
            temp += str2.charAt(i);
 
            // Insert the prefix into hashset
            set.add(temp);
        }
 
        // Re-initialize temp string
        // to empty string
        temp = "";
 
        // Iterate the string in reverse direction
        for (int i = l2 - 1; i >= 0; i--) {
 
            // Add current character to temp
            temp += str2.charAt(i);
 
            // Reverse the string temp
            temp = new StringBuffer(temp).reverse().toString();
 
            // Insert the suffix into the hashset
            set.add(temp);
 
            // Reverse the string temp again
            temp = new StringBuffer(temp).reverse().toString();
 
        }
 
        // Initialize dp array to store the answer
        int[] dp = new int[str1.length() + 1];
        Arrays.fill(dp, -1);
        dp[0] = 0;
 
        // Check for all substrings starting
        // and ending at every indices
        for (int i = 0; i < l1; i++) {
            for (int j = 1; j <= l1 - i; j++) {
 
                // HashSet contains the substring
                if (set.contains(str1.substring(i, i + j))) {
 
                    if (dp[i] == -1) {
                        continue;
                    }
                    if (dp[i + j] == -1) {
                        dp[i + j] = dp[i] + 1;
                    } else {
 
                        // Minimum of dp[i + j] and
                        // dp[i] + 1 will be stored
                        dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
                    }
                }
            }
        }
 
        // Return the answer
        return dp[str1.length()];
    }
 
    // Driver Code
    public static void main(String args[]) {
        String str = "GEEKSFORGEEKS", wrd = "SFORGEEK";
 
        // Print the string
        System.out.println(partCount(str, wrd));
    }
}
 
// This code is contributed by gfgking.


Python3




# Python3 implementation for the above approach
 
# Function to find minimum number of
# concatenation of prefix and suffix
# of str2 to make str1
def partCount(str1, str2):
 
    # Initialize a set
    se = set()
 
    # Initialize a temporary string
    temp = ""
 
    l1 = len(str1)
    l2 = len(str2)
 
    # Iterate the string str2
    # from left to right
    for i in range(0, l2):
 
                # Add current character
                # to string temp
        temp += str2[i]
 
        # Insert the prefix into hashset
        se.add(temp)
 
        # Re-initialize temp string
        # to empty string
    temp = []
 
    # Iterate the string in reverse direction
    for i in range(l2 - 1, -1, -1):
 
                # Add current character to temp
        temp.append(str2[i])
 
        # Reverse the string temp
        temp.reverse()
 
        # Insert the suffix into the hashset
        se.add(''.join(temp))
 
        # Reverse the string temp again
        temp.reverse()
 
        # Initialize dp array to store the answer
    dp = [-1 for _ in range(len(str1) + 1)]
    dp[0] = 0
 
    # Check for all substrings starting
    # and ending at every indices
    for i in range(0, l1, 1):
        for j in range(1, l1 - i + 1):
 
                        # HashSet contains the substring
            if (str1[i:i+j] in se):
 
                if (dp[i] == -1):
                    continue
 
                if (dp[i + j] == -1):
                    dp[i + j] = dp[i] + 1
 
                else:
 
                    # Minimum of dp[i + j] and
                    # dp[i] + 1 will be stored
                    dp[i + j] = min(dp[i + j], dp[i] + 1)
 
        # Return the answer
    return dp[len(str1)]
 
# Driver Code
if __name__ == "__main__":
 
    str = "GEEKSFORGEEKS"
    wrd = "SFORGEEK"
 
    # Print the string
    print(partCount(str, wrd))
 
    # This code is contributed by rakeshsahni


C#




// C# implementation for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
    public static string Reverse(string Input)
    {
      
    // Converting string to character array
    char[] charArray = Input.ToCharArray();
      
    // Declaring an empty string
    string reversedString = String.Empty;
      
    // Iterating the each character from right to left
    for(int i = charArray.Length - 1; i > -1; i--)
    {
          
        // Append each character to the reversedstring.
        reversedString += charArray[i];
    }
      
    // Return the reversed string.
    return reversedString;
    }
 
    // Function to find minimum number of
    // concatenation of prefix and suffix
    // of str2 to make str1
    public static int partCount(string str1, string str2) {
 
        // Initialize a set
        HashSet<String> set = new HashSet<String>();
 
        // Initialize a temporary string
        string temp = "";
 
        int l1 = str1.Length, l2 = str2.Length;
 
        // Iterate the string str2
        // from left to right
        for (int i = 0; i < l2; i++) {
 
            // Add current character
            // to string temp
            temp += str2[i];
 
            // Insert the prefix into hashset
            set.Add(temp);
        }
 
        // Re-initialize temp string
        // to empty string
        temp = "";
 
        // Iterate the string in reverse direction
        for (int i = l2 - 1; i >= 0; i--) {
 
            // Add current character to temp
            temp += str2[i];
 
            // Reverse the string temp
            temp = Reverse(temp);
 
            // Insert the suffix into the hashet
            set.Add(temp);
 
            // Reverse the string temp again
            temp = Reverse(temp);
 
        }
 
        // Initialize dp array to store the answer
        int[] dp = new int[str1.Length + 1];
        for(int j=0; j<dp.Length;j++)
        {
            dp[j] = -1;
        }
 
        dp[0] = 0;
 
        // Check for all substrings starting
        // and ending at every indices
        for (int i = 0; i < l1; i++) {
            for (int j = 1; j <= l1 - i; j++) {
 
                // HashSet contains the substring
                if (set.Contains(str1.Substring(i, j))) {
 
                    if (dp[i] == -1) {
                        continue;
                    }
                    if (dp[i + j] == -1) {
                        dp[i + j] = dp[i] + 1;
                    } else {
 
                        // Minimum of dp[i + j] and
                        // dp[i] + 1 will be stored
                        dp[i + j] = Math.Min(dp[i + j], dp[i] + 1);
                    }
                }
            }
        }
 
        // Return the answer
        return dp[str1.Length];
    }
 
    // Driver code
    static public void Main(String[] args)
    {
        string str = "GEEKSFORGEEKS", wrd = "SFORGEEK";
 
        // Print the string
        Console.WriteLine(partCount(str, wrd));
    }
}
 
// This code is contributed by code_hunt.


Javascript




<script>
       // JavaScript Program to implement
       // the above approach
 
       // Function to find minimum number of
       // concatenation of prefix and suffix
       // of str2 to make str1
       function partCount(str1, str2) {
 
           // Initialize a set
           let set = new Set();
 
           // Initialize a temporary string
           let temp = "";
 
           let l1 = str1.length, l2 = str2.length;
 
           // Iterate the string str2
           // from left to right
           for (let i = 0; i < l2; i++) {
 
               // Add current character
               // to string temp
               temp = temp + str2.charAt(i);
 
               // Insert the prefix into hashset
               set.add(temp);
           }
 
           // Re-initialize temp string
           // to empty string
           temp = "";
 
           // Iterate the string in reverse direction
           for (let i = l2 - 1; i >= 0; i--) {
 
               // Add current character to temp
               temp = temp + str2.charAt(i);
 
               // Reverse the string temp
               temp = temp.split('').reduce((r, c) => c + r, '');
 
               // Insert the suffix into the hashset
               set.add(temp);
 
               // Reverse the string temp again
               temp = temp.split('').reduce((r, c) => c + r, '');
           }
 
           // Initialize dp array to store the answer
           let dp = new Array(str1.length + 1).fill(-1);
 
 
           dp[0] = 0;
 
           // Check for all substrings starting
           // and ending at every indices
           for (let i = 0; i < l1; i++) {
               for (let j = 1; j <= l1 - i; j++) {
 
                   // HashSet contains the substring
                   if (set.has(str1.substring(i, j))) {
 
                       if (dp[i] == -1) {
                           continue;
                       }
                       if (dp[i + j] == -1) {
                           dp[i + j] = dp[i] + 1;
                       }
                       else {
 
                           // Minimum of dp[i + j] and
                           // dp[i] + 1 will be stored
                           dp[i + j]
                               = Math.min(dp[i + j], dp[i] + 1);
                       }
                   }
               }
           }
            
           // Return the answer
           return dp[str1.length] + 1;
       }
 
       // Driver Code
       let str = "GEEKSFORGEEKS"
       let wrd = "SFORGEEK";
 
       // Print the string
       document.write(partCount(str, wrd));
 
   // This code is contributed by Potta Lokesh
   </script>


Output

3

Time Complexity: O(N^2), where N is length of str1
Auxiliary Space: O(N^2)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads