Minimum number of substrings the given string can be splitted into that satisfy the given conditions
Last Updated :
14 Sep, 2023
Given a string str and a string array arr[], the task is to find the minimum count of substrings this can be split into such that every substring is present in the given string array arr[].
Examples:
Input: str = “111112”, arr[] = {“11”, “111”, “11111”, “2”}
Output: 2
“11111” and “2” are the required substrings.
“11”, “111” and “2” can also be a valid answer
but it is not the minimum.
Input: str = “123456”, arr[] = {“1”, “12345”, “2345”, “56”, “23”, “456”}
Output: 3
Approach: Iterate the string from index 0 and build the prefix string, if the prefix string exists in the given array (a set can be used to check this) then call the function again from the next position in the string and keep track of the overall minimum count of substrings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
unordered_set<string> uSet;
int minCnt = INT_MAX;
void findSubStr(string str, int cnt, int start)
{
if (start == str.length()) {
minCnt = min(cnt, minCnt);
}
for ( int len = 1; len <= (str.length() - start); len++) {
string subStr = str.substr(start, len);
if (uSet.find(subStr) != uSet.end()) {
findSubStr(str, cnt + 1, start + len);
}
}
}
void findMinSubStr(string arr[], int n, string str)
{
for ( int i = 0; i < n; i++)
uSet.insert(arr[i]);
findSubStr(str, 0, 0);
}
int main()
{
string str = "123456" ;
string arr[] = { "1" , "12345" , "2345" ,
"56" , "23" , "456" };
int n = sizeof (arr) / sizeof (string);
findMinSubStr(arr, n, str);
cout << minCnt;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static Set<String> uSet = new HashSet<String>();
static int minCnt = Integer.MAX_VALUE;
static void findSubStr(String str, int cnt, int start)
{
if (start == str.length())
{
minCnt = Math.min(cnt, minCnt);
}
for ( int len = 1 ;
len <= (str.length() - start); len++)
{
String subStr = str.substring(start, start + len);
if (uSet.contains(subStr))
{
findSubStr(str, cnt + 1 , start + len);
}
}
}
static void findMinSubStr(String arr[],
int n, String str)
{
for ( int i = 0 ; i < n; i++)
uSet.add(arr[i]);
findSubStr(str, 0 , 0 );
}
public static void main(String args[])
{
String str = "123456" ;
String arr[] = { "1" , "12345" , "2345" ,
"56" , "23" , "456" };
int n = arr.length;
findMinSubStr(arr, n, str);
System.out.print(minCnt);
}
}
|
Python3
import sys
uSet = set ();
minCnt = sys.maxsize;
def findSubStr(string, cnt, start) :
global minCnt;
if (start = = len (string)) :
minCnt = min (cnt, minCnt);
for length in range ( 1 , len (string) - start + 1 ) :
subStr = string[start : start + length];
if subStr in uSet :
findSubStr(string, cnt + 1 , start + length);
def findMinSubStr(arr, n, string) :
for i in range (n) :
uSet.add(arr[i]);
findSubStr(string, 0 , 0 );
if __name__ = = "__main__" :
string = "123456" ;
arr = [ "1" , "12345" , "2345" ,
"56" , "23" , "456" ];
n = len (arr);
findMinSubStr(arr, n, string);
print (minCnt);
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static HashSet<String> uSet = new HashSet<String>();
static int minCnt = int .MaxValue;
static void findSubStr(String str, int cnt, int start)
{
if (start == str.Length)
{
minCnt = Math.Min(cnt, minCnt);
}
for ( int len = 1;
len <= (str.Length - start); len++)
{
String subStr = str.Substring(start, len);
if (uSet.Contains(subStr))
{
findSubStr(str, cnt + 1, start + len);
}
}
}
static void findMinSubStr(String []arr,
int n, String str)
{
for ( int i = 0; i < n; i++)
uSet.Add(arr[i]);
findSubStr(str, 0, 0);
}
public static void Main(String []args)
{
String str = "123456" ;
String []arr = { "1" , "12345" , "2345" ,
"56" , "23" , "456" };
int n = arr.Length;
findMinSubStr(arr, n, str);
Console.WriteLine(minCnt);
}
}
|
Javascript
<script>
var uSet = new Set();
var minCnt = 1000000000;
function findSubStr( str, cnt, start)
{
if (start == str.length) {
minCnt = Math.min(cnt, minCnt);
}
for ( var len = 1; len <= (str.length - start); len++) {
var subStr = str.substring(start, start+len);
if (uSet.has(subStr)) {
findSubStr(str, cnt + 1, start + len);
}
}
}
function findMinSubStr(arr, n, str)
{
for ( var i = 0; i < n; i++)
uSet.add(arr[i]);
findSubStr(str, 0, 0);
}
var str = "123456" ;
var arr = [ "1" , "12345" , "2345" ,
"56" , "23" , "456" ];
var n = arr.length;
findMinSubStr(arr, n, str);
document.write( minCnt);
</script>
|
Method 2:Using Dynamic Programming
Approach:
we use dp in our approach, we can use the array dp[]. Because the minimum count of substrings up to the first index is always 0 and the minimum count of substrings up to every subsequent index is initially equal to the length of the substring from the beginning of the string to that index, we can initialize dp[0] = 0 and dp[i] to i for i > 0. Finally, dp[len] is returned, where len is the length of the input string str. This will tell us the smallest number of substrings that str can be split into so that each substring is present in arr[].
Implementation:
C++
#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
int minSubstringCount(string str, string arr[], int n)
{
int len = str.length();
int dp[len + 1];
dp[0] = 0;
unordered_set<string> set(arr, arr + n);
for ( int i = 1; i <= len; i++) {
dp[i] = i;
for ( int j = 0; j < i; j++) {
string sub = str.substr(j, i - j);
if (set.find(sub) != set.end()) {
dp[i] = min(dp[i], dp[j] + 1);
}
}
}
return dp[len];
}
int main()
{
string str = "111112" ;
string arr[] = { "11" , "111" , "11111" , "2" };
int n = sizeof (arr) / sizeof (arr[0]);
int result = minSubstringCount(str, arr, n);
cout << result << endl;
return 0;
}
|
Java
import java.util.HashSet;
public class GFG {
static int minSubstringCount(String str, String[] arr) {
int len = str.length();
int [] dp = new int [len + 1 ];
dp[ 0 ] = 0 ;
HashSet<String> set = new HashSet<>();
for (String s : arr) {
set.add(s);
}
for ( int i = 1 ; i <= len; i++) {
dp[i] = i;
for ( int j = 0 ; j < i; j++) {
String sub = str.substring(j, i);
if (set.contains(sub)) {
dp[i] = Math.min(dp[i], dp[j] + 1 );
}
}
}
return dp[len];
}
public static void main(String[] args) {
String str = "111112" ;
String[] arr = { "11" , "111" , "11111" , "2" };
int result = minSubstringCount(str, arr);
System.out.println(result);
}
}
|
Python3
def min_substring_count(s, arr):
length = len (s)
dp = [i for i in range (length + 1 )]
substring_set = set (arr)
for i in range ( 1 , length + 1 ):
for j in range (i):
sub = s[j:i]
if sub in substring_set:
dp[i] = min (dp[i], dp[j] + 1 )
return dp[length]
if __name__ = = "__main__" :
s = "111112"
arr = [ "11" , "111" , "11111" , "2" ]
result = min_substring_count(s, arr)
print (result)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int MinSubstringCount( string str, string [] arr,
int n)
{
int len = str.Length;
int [] dp = new int [len + 1];
dp[0] = 0;
HashSet< string > set = new HashSet< string >(
arr);
for ( int i = 1; i <= len; i++) {
dp[i] = i;
for ( int j = 0; j < i; j++) {
string sub = str.Substring(
j, i - j);
if ( set .Contains(sub)) {
dp[i] = Math.Min(dp[i], dp[j] + 1);
}
}
}
return dp[len];
}
static void Main( string [] args)
{
string str = "111112" ;
string [] arr = { "11" , "111" , "11111" ,
"2" };
int n = arr.Length;
int result = MinSubstringCount(str, arr, n);
Console.WriteLine(result);
}
}
|
Javascript
function minSubstringCount(str, arr) {
const len = str.length;
const dp = new Array(len + 1).fill(0);
dp[0] = 0;
const set = new Set(arr);
for (let i = 1; i <= len; i++) {
dp[i] = i;
for (let j = 0; j < i; j++) {
const sub = str.substring(j, i);
if (set.has(sub)) {
dp[i] = Math.min(dp[i], dp[j] + 1);
}
}
}
return dp[len];
}
const str = "111112" ;
const arr = [ "11" , "111" , "11111" , "2" ];
const result = minSubstringCount(str, arr);
console.log(result);
|
Time Complexity: O(n^3),where n is the length of the input string str.
Auxiliary Space: O(n)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...