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

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 programing to find the 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 Trie
struct TrieNode {
    TrieNode* child[26] = { NULL };
};
  
// Function to insert a node in the
// Trie Data Structure
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 string
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
    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 Code
int main()
{
    string S1 = "abcdab";
    string S2 = "dabc";
  
    cout << minCuts(S1, S2);
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to split the
# string into minimum number of
# parts such that each part is also
# present in the another string
INF = 1e9 + 9
  
# Node of Trie
class TrieNode():
    def __init__(self):
  
        self.child = [None] * 26
  
# Function to insert a node in the
# Trie Data Structure
def 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 string
def 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 Code
S1 = "abcdab"
S2 = "dabc"
  
print(minCuts(S1, S2))
  
# This code is contributed by Shivam Singh

chevron_right


Output:

2

Time Complexity :  O(N^2)
Space Complexity :  O(N^2)

competitive-programming-img




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.



Improved By : SHIVAMSINGH67