Related Articles

Related Articles

Split the string into minimum parts such that each part is in the another string
  • Last Updated : 10 Sep, 2020

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:
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 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


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to split the
// String into minimum number of
// parts such that each part is also
// present in the another String
import java.util.*;
 
class GFG{
 
static int INF = (int)(1e9 + 9);
 
// Node of Trie
static class TrieNode
{
    TrieNode []child = new TrieNode[26];
};
 
// Function to insert a node in the
// Trie Data Structure
static 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 String
static 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 Code
public static void main(String[] args)
{
    String S1 = "abcdab";
    String S2 = "dabc";
 
    System.out.print(minCuts(S1, S2));
}
}
 
// This code is contributed by Rajput-Ji

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


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
using System;
class GFG{
 
static int INF = (int)(1e9 + 9);
 
// Node of Trie
class TrieNode
{
    public TrieNode []child =
                    new TrieNode[26];
};
 
// Function to insert a node in the
// Trie Data Structure
static 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
static 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 Code
public static void Main(String[] args)
{
    String S1 = "abcdab";
    String S2 = "dabc";
    Console.Write(minCuts(S1, S2));
}
}
// This code is contributed by shikhasingrajput

chevron_right


Output: 

2


Time Complexity : 

O(N^2)

Space Complexity : 

O(N^2)

competitive-programming-img




My Personal Notes arrow_drop_up
Recommended Articles
Page :