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 str2Input: 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++ 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 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 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# 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. |
<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>
|
3
Time Complexity: O(N^2), where N is length of str1
Auxiliary Space: O(N^2)