Split the string into minimum parts such that each part is in the another string
Last Updated :
27 Mar, 2023
Given two strings A and B, the task is to split the string A into the minimum number of substrings such that each substring is in the string B.
Note: If there is no way to split the string, then print -1
Examples:
Input: A = “abcdab”, B = “dabc”
Output: 2
Explanation:
The two substrings of A which is also present in B are –
{“abc”, “dab”}
Input: A = “abcde”, B = “edcb”
Output: -1
Explanation:
There is no way to split the string A into substring
Such that each string is also present in the B.
Approach:
- Construct a trie of every substring of B.
- After that, we’ll use Dynamic programming to find the minimum number of parts to break the string A such that every part is a substring of B.
Recurrence Relation in Dynamic Programming:
dp[i] = minimum number of parts to break the string A up to ith prefix.
dp[0] = 0
for i in {0, S1.length}
for j in {i, S1.length}
if(S1[i, ... j] is found in trie
dp[j] = min(dp[j], dp[i] + 1);
else
break;
dp[S1.length] is the
minimum number of parts.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 9;
struct TrieNode {
TrieNode* child[26] = { NULL };
};
void insert( int idx, string& s,
TrieNode* root)
{
TrieNode* temp = root;
for ( int i = idx; i < s.length(); i++) {
if (temp->child[s[i] - 'a' ] == NULL)
temp->child[s[i] - 'a' ] = new TrieNode;
temp = temp->child[s[i] - 'a' ];
}
}
int minCuts(string S1, string S2)
{
int n1 = S1.length();
int n2 = S2.length();
TrieNode* root = new TrieNode;
for ( int i = 0; i < n2; i++) {
insert(i, S2, root);
}
vector< int > dp(n1 + 1, INF);
dp[0] = 0;
for ( int i = 0; i < n1; i++) {
TrieNode* temp = root;
for ( int j = i + 1; j <= n1; j++) {
if (temp->child[S1[j - 1] - 'a' ] == NULL)
break ;
dp[j] = min(dp[j], dp[i] + 1);
temp = temp->child[S1[j - 1] - 'a' ];
}
}
if (dp[n1] >= INF)
return -1;
else
return dp[n1];
}
int main()
{
string S1 = "abcdab" ;
string S2 = "dabc" ;
cout << minCuts(S1, S2);
}
|
Java
import java.util.*;
class GFG{
static int INF = ( int )(1e9 + 9 );
static class TrieNode
{
TrieNode []child = new TrieNode[ 26 ];
};
static void insert( int idx, String s,
TrieNode root)
{
TrieNode temp = root;
for ( int i = idx; i < s.length(); i++)
{
if (temp.child[s.charAt(i) - 'a' ] == null )
temp.child[s.charAt(i) - 'a' ] = new TrieNode();
temp = temp.child[s.charAt(i) - 'a' ];
}
}
static int minCuts(String S1, String S2)
{
int n1 = S1.length();
int n2 = S2.length();
TrieNode root = new TrieNode();
for ( int i = 0 ; i < n2; i++)
{
insert(i, S2, root);
}
int []dp = new int [n1 + 1 ];
Arrays.fill(dp, INF);
dp[ 0 ] = 0 ;
for ( int i = 0 ; i < n1; i++)
{
TrieNode temp = root;
for ( int j = i + 1 ; j <= n1; j++)
{
if (temp.child[S1.charAt(j - 1 ) - 'a' ] == null )
break ;
dp[j] = Math.min(dp[j], dp[i] + 1 );
temp = temp.child[S1.charAt(j - 1 ) - 'a' ];
}
}
if (dp[n1] >= INF)
return - 1 ;
else
return dp[n1];
}
public static void main(String[] args)
{
String S1 = "abcdab" ;
String S2 = "dabc" ;
System.out.print(minCuts(S1, S2));
}
}
|
Python3
INF = 1e9 + 9
class TrieNode():
def __init__( self ):
self .child = [ None ] * 26
def insert(idx, s, root):
temp = root
for i in range (idx, len (s)):
if temp.child[ ord (s[i]) -
ord ( 'a' )] = = None :
temp.child[ ord (s[i]) -
ord ( 'a' )] = TrieNode()
temp = temp.child[ ord (s[i]) - ord ( 'a' )]
def minCuts(S1, S2):
n1 = len (S1)
n2 = len (S2)
root = TrieNode()
for i in range (n2):
insert(i, S2, root)
dp = [INF] * (n1 + 1 )
dp[ 0 ] = 0
for i in range (n1):
temp = root
for j in range (i + 1 , n1 + 1 ):
if temp.child[ ord (S1[j - 1 ]) -
ord ( 'a' )] = = None :
break
dp[j] = min (dp[j], dp[i] + 1 )
temp = temp.child[ ord (S1[j - 1 ]) -
ord ( 'a' )]
if dp[n1] > = INF:
return - 1
else :
return dp[n1]
S1 = "abcdab"
S2 = "dabc"
print (minCuts(S1, S2))
|
C#
using System;
class GFG{
static int INF = ( int )(1e9 + 9);
class TrieNode
{
public TrieNode []child =
new TrieNode[26];
};
static void insert( int idx, String s,
TrieNode root)
{
TrieNode temp = root;
for ( int i = idx; i < s.Length; i++)
{
if (temp.child[s[i] - 'a' ] == null )
temp.child[s[i] - 'a' ] =
new TrieNode();
temp = temp.child[s[i] - 'a' ];
}
}
static int minCuts(String S1, String S2)
{
int n1 = S1.Length;
int n2 = S2.Length;
TrieNode root = new TrieNode();
for ( int i = 0; i < n2; i++)
{
insert(i, S2, root);
}
int []dp = new int [n1 + 1];
for ( int i = 0; i <= n1; i++)
dp[i] = INF;
dp[0] = 0;
for ( int i = 0; i < n1; i++)
{
TrieNode temp = root;
for ( int j = i + 1; j <= n1; j++)
{
if (temp.child[S1[j-1] - 'a' ] == null )
break ;
dp[j] = Math.Min(dp[j], dp[i] + 1);
temp = temp.child[S1[j - 1] - 'a' ];
}
}
if (dp[n1] >= INF)
return -1;
else
return dp[n1];
}
public static void Main(String[] args)
{
String S1 = "abcdab" ;
String S2 = "dabc" ;
Console.Write(minCuts(S1, S2));
}
}
|
Javascript
<script>
let INF = (1e9 + 9);
class Node
{
constructor()
{
}
}
function TrieNode()
{
let temp = new Node();
temp.child = new Node(26);
for (let i = 0; i < 26; i++)
{
temp.child[i] = null ;
}
return temp;
}
function insert(idx, s, root)
{
let temp = root;
for (let i = idx; i < s.length; i++)
{
if (temp.child[s[i].charCodeAt() - 'a' .charCodeAt()] == null )
temp.child[s[i].charCodeAt() - 'a' .charCodeAt()] = new TrieNode();
temp = temp.child[s[i].charCodeAt() - 'a' .charCodeAt()];
}
}
function minCuts(S1, S2)
{
let n1 = S1.length;
let n2 = S2.length;
let root = new TrieNode();
for (let i = 0; i < n2; i++)
{
insert(i, S2, root);
}
let dp = new Array(n1 + 1);
dp.fill(INF);
dp[0] = 0;
for (let i = 0; i < n1; i++)
{
let temp = root;
for (let j = i + 1; j <= n1; j++)
{
if (temp.child[S1[j - 1].charCodeAt() - 'a' .charCodeAt()] == null )
break ;
dp[j] = Math.min(dp[j], dp[i] + 1);
temp = temp.child[S1[j - 1].charCodeAt() - 'a'.charCodeAt()];
}
}
if (dp[n1] >= INF)
return -1;
else
return dp[n1];
}
let S1 = "abcdab" ;
let S2 = "dabc" ;
document.write(minCuts(S1, S2));
</script>
|
Time complexity: O(|S1||S2|^2) where |S1| and |S2| are the lengths of S1 and S2, respectively.
Auxiliary Space: The space complexity of the program is dominated by the size of the Trie data structure. In the worst case, the size of the Trie will be proportional to the size of S2. So, the space complexity of the program is O(|S2|)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...