Split the string into minimum parts such that each part is in the another string - GeeksforGeeks

09 Sep, 2021
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++
Java
Python3
C#
Javascript
// C++ implementation to split the// string into minimum number of// parts such that each part is also// present in the another string #include <bits/stdc++.h>using namespace std; const int INF = 1e9 + 9; // Node of Triestruct TrieNode {    TrieNode* child[26] = { NULL };}; // Function to insert a node in the// Trie Data Structurevoid insert(int idx, string& s,            TrieNode* root){    TrieNode* temp = root;    for (int i = idx; i < s.length(); i++) {         // Inserting every character from idx        // till end to string into trie        if (temp->child[s[i] - 'a'] == NULL)             // if there is no edge corresponding            // to the ith character,            // then make a new node            temp->child[s[i] - 'a'] = new TrieNode;         temp = temp->child[s[i] - 'a'];    }} // Function to find the minimum// number of parts such that each// part is present into another stringint minCuts(string S1, string S2){    int n1 = S1.length();    int n2 = S2.length();     // Making a new trie    TrieNode* root = new TrieNode;     for (int i = 0; i < n2; i++) {         // Inserting every substring        // of S2 in trie        insert(i, S2, root);    }     // Creating dp array and    // init it with infinity    vector<int> dp(n1 + 1, INF);     // Base Case    dp[0] = 0;    for (int i = 0; i < n1; i++) {         // Starting the cut from ith character        // taking temporary node pointer        // for checking whether the substring        // [i, j) is present in trie of not        TrieNode* temp = root;        for (int j = i + 1; j <= n1; j++) {            if (temp->child[S1[j - 1] - 'a'] == NULL)                 // if the jth character is not in trie                // we'll break                break;             // Updating the the ending of            // jth character with dp[i] + 1            dp[j] = min(dp[j], dp[i] + 1);             // Descending the trie pointer            temp = temp->child[S1[j - 1] - 'a'];        }    }     // Answer not possible    if (dp[n1] >= INF)        return -1;    else        return dp[n1];} // Driver Codeint main(){    string S1 = "abcdab";    string S2 = "dabc";     cout << minCuts(S1, S2);}
// Java implementation to split the// String into minimum number of// parts such that each part is also// present in the another Stringimport java.util.*; class GFG{ static int INF = (int)(1e9 + 9); // Node of Triestatic class TrieNode{    TrieNode []child = new TrieNode[26];}; // Function to insert a node in the// Trie Data Structurestatic void insert(int idx, String s,                   TrieNode root){    TrieNode temp = root;    for(int i = idx; i < s.length(); i++)    {                 // Inserting every character from idx        // till end to String into trie        if (temp.child[s.charAt(i) - 'a'] == null)             // If there is no edge corresponding            // to the ith character,            // then make a new node            temp.child[s.charAt(i) - 'a'] = new TrieNode();         temp = temp.child[s.charAt(i) - 'a'];    }} // Function to find the minimum// number of parts such that each// part is present into another Stringstatic int minCuts(String S1, String S2){    int n1 = S1.length();    int n2 = S2.length();     // Making a new trie    TrieNode root = new TrieNode();     for(int i = 0; i < n2; i++)    {                 // Inserting every subString        // of S2 in trie        insert(i, S2, root);    }     // Creating dp array and    // init it with infinity    int []dp = new int[n1 + 1];    Arrays.fill(dp, INF);         // Base Case    dp[0] = 0;         for(int i = 0; i < n1; i++)    {                 // Starting the cut from ith character        // taking temporary node pointer        // for checking whether the subString        // [i, j) is present in trie of not        TrieNode temp = root;        for(int j = i + 1; j <= n1; j++)        {            if (temp.child[S1.charAt(j - 1) - 'a'] == null)                 // If the jth character is not in trie                // we'll break                break;             // Updating the the ending of            // jth character with dp[i] + 1            dp[j] = Math.min(dp[j], dp[i] + 1);             // Descending the trie pointer            temp = temp.child[S1.charAt(j - 1) - 'a'];        }    }     // Answer not possible    if (dp[n1] >= INF)        return -1;    else        return dp[n1];} // Driver Codepublic static void main(String[] args){    String S1 = "abcdab";    String S2 = "dabc";     System.out.print(minCuts(S1, S2));}} // This code is contributed by Rajput-Ji
# Python3 implementation to split the# string into minimum number of# parts such that each part is also# present in the another stringINF = 1e9 + 9 # Node of Trieclass TrieNode():    def __init__(self):         self.child = [None] * 26 # Function to insert a node in the# Trie Data Structuredef insert(idx, s, root):         temp = root     for i in range(idx, len(s)):                 # Inserting every character from idx        # till end to string into trie        if temp.child[ord(s[i]) -                      ord('a')] == None:                         # If there is no edge corresponding            # to the ith character,            # then make a new node            temp.child[ord(s[i]) -                       ord('a')] = TrieNode()         temp = temp.child[ord(s[i]) - ord('a')] # Function to find the minimum# number of parts such that each# part is present into another stringdef minCuts(S1, S2):         n1 = len(S1)    n2 = len(S2)     # Making a new trie    root = TrieNode()     for i in range(n2):                 # Inserting every substring        # of S2 in trie        insert(i, S2, root)     # Creating dp array and    # init it with infinity    dp = [INF] * (n1 + 1)     # Base Case    dp[0] = 0     for i in range(n1):                 # Starting the cut from ith character        # taking temporary node pointer        # for checking whether the substring        # [i, j) is present in trie of not        temp = root        for j in range(i + 1, n1 + 1):            if temp.child[ord(S1[j - 1]) -                          ord('a')] == None:                                 # If the jth character is not                # in trie we'll break                break             # Updating the the ending of            # jth character with dp[i] + 1            dp[j] = min(dp[j], dp[i] + 1)             # Descending the trie pointer            temp = temp.child[ord(S1[j - 1]) -                              ord('a')]     # Answer not possible    if dp[n1] >= INF:        return -1    else:        return dp[n1] # Driver CodeS1 = "abcdab"S2 = "dabc" print(minCuts(S1, S2)) # This code is contributed by Shivam Singh
// C# implementation to split the// String into minimum number of// parts such that each part is also// present in the another Stringusing System;class GFG{ static int INF = (int)(1e9 + 9); // Node of Trieclass TrieNode{    public TrieNode []child =                    new TrieNode[26];}; // Function to insert a node in the// Trie Data Structurestatic void insert(int idx, String s,                   TrieNode root){    TrieNode temp = root;    for(int i = idx; i < s.Length; i++)    {               // Inserting every character from idx        // till end to String into trie        if (temp.child[s[i] - 'a'] == null)             // If there is no edge corresponding            // to the ith character,            // then make a new node            temp.child[s[i] - 'a'] =                       new TrieNode();         temp = temp.child[s[i] - 'a'];    }} // Function to find the minimum// number of parts such that each// part is present into another Stringstatic int minCuts(String S1, String S2){    int n1 = S1.Length;    int n2 = S2.Length;     // Making a new trie    TrieNode root = new TrieNode();     for(int i = 0; i < n2; i++)    {               // Inserting every subString        // of S2 in trie        insert(i, S2, root);    }     // Creating dp array and    // init it with infinity    int []dp = new int[n1 + 1];    for(int i = 0; i <= n1; i++)        dp[i] = INF;         // Base Case    dp[0] = 0;         for(int i = 0; i < n1; i++)    {               // Starting the cut from ith character        // taking temporary node pointer        // for checking whether the subString        // [i, j) is present in trie of not        TrieNode temp = root;        for(int j = i + 1; j <= n1; j++)        {            if (temp.child[S1[j-1] - 'a'] == null)                 // If the jth character is not in trie                // we'll break                break;             // Updating the the ending of            // jth character with dp[i] + 1            dp[j] = Math.Min(dp[j], dp[i] + 1);             // Descending the trie pointer            temp = temp.child[S1[j - 1] - 'a'];        }    }     // Answer not possible    if (dp[n1] >= INF)        return -1;    else        return dp[n1];} // Driver Codepublic static void Main(String[] args){    String S1 = "abcdab";    String S2 = "dabc";    Console.Write(minCuts(S1, S2));}}// This code is contributed by shikhasingrajput
<script>    // Javascript implementation to split the    // String into minimum number of    // parts such that each part is also    // present in the another String     let INF = (1e9 + 9);          // Node of Trie    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 to insert a node in the    // Trie Data Structure    function insert(idx, s, root)    {        let temp = root;        for(let i = idx; i < s.length; i++)        {             // Inserting every character from idx            // till end to String into trie            if (temp.child[s[i].charCodeAt() - 'a'.charCodeAt()] == null)                 // If there is no edge corresponding                // to the ith character,                // then make a new node                temp.child[s[i].charCodeAt() - 'a'.charCodeAt()] = new TrieNode();             temp = temp.child[s[i].charCodeAt() - 'a'.charCodeAt()];        }    }     // Function to find the minimum    // number of parts such that each    // part is present into another String    function minCuts(S1, S2)    {        let n1 = S1.length;        let n2 = S2.length;         // Making a new trie        let root = new TrieNode();         for(let i = 0; i < n2; i++)        {             // Inserting every subString            // of S2 in trie            insert(i, S2, root);        }         // Creating dp array and        // init it with infinity        let dp = new Array(n1 + 1);        dp.fill(INF);         // Base Case        dp[0] = 0;         for(let i = 0; i < n1; i++)        {             // Starting the cut from ith character            // taking temporary node pointer            // for checking whether the subString            // [i, j) is present in trie of not            let temp = root;            for(let j = i + 1; j <= n1; j++)            {                if (temp.child[S1[j - 1].charCodeAt() - 'a'.charCodeAt()] == null)                     // If the jth character is not in trie                    // we'll break                    break;                 // Updating the the ending of                // jth character with dp[i] + 1                dp[j] = Math.min(dp[j], dp[i] + 1);                 // Descending the trie pointer                temp = temp.child[S1[j - 1].charCodeAt() - 'a'.charCodeAt()];            }        }         // Answer not possible        if (dp[n1] >= INF)            return -1;        else            return dp[n1];    }         let S1 = "abcdab";    let S2 = "dabc";      document.write(minCuts(S1, S2));         // This code is contributed by mukesh07.</script>
2
Time Complexity : 
 
Space Complexity : 
 
SHIVAMSINGH67
Rajput-Ji
shikhasingrajput
mukesh07
sweetyty
Competitive Programming
Dynamic Programming
Strings
Tree
Strings
Dynamic Programming
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Breadth First Traversal ( BFS ) on a 2D array
Runtime Errors
Multistage Graph (Shortest Path)
Most important type of Algorithms
Shortest path in a directed graph by Dijkstra’s algorithm
0-1 Knapsack Problem | DP-10
Program for Fibonacci numbers
Largest Sum Contiguous Subarray
Longest Common Subsequence | DP-4
Bellman–Ford Algorithm | DP-23