Find minimum number of Substrings with unique characters
Last Updated :
19 Apr, 2023
Given string ‘s’, the task is to divide a given string s into multiple substrings, with each substring containing only unique characters. This means that no character should be repeated within a single substring. The goal is to find the minimum number of such substrings required to satisfy this condition.
Examples:
Input: s = “abacaba”
Output: 4
Explanation: Two possible partitions are (“a”, “ba”, “cab”, “a”) and (“ab”, “a”, “ca”, “ba”). It can be shown that 4 is the minimum number of substrings needed.
Input: s = “ssssss”
Output: 6
Explanation: The only valid partition is (“s”, “s”, “s”, “s”, “s”, “s”).
Naive Approach: The basic way to solve the problem follows the below idea:
- We initialize an empty set and iterate through the given string. For each character encountered, we check if it is already present in the set.
- If it is, this means that we need to start a new substring since the current substring has a repeated character. We increase our answer variable and clear the set to start a new substring. We then add the current character to the set.
- After iterating through the entire string, the value of the answer variable gives us the minimum number of substrings required to partition the given string such that each substring has unique characters.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int partitionString(string s)
{
unordered_set< char > st;
int ans = 1;
for ( int i = 0; i < s.size(); i++) {
if (st.find(s[i]) != st.end()) {
ans++;
st.clear();
}
st.insert(s[i]);
}
return ans;
}
int main()
{
string S = "abacaba" ;
cout << "Minimum Number of Substrings with Unique "
"Characters: "
<< partitionString(S);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int partitionString(String s)
{
Set<Character> set = new HashSet<>();
int ans = 1 ;
for ( int i = 0 ; i < s.length(); i++) {
if (set.contains(s.charAt(i))) {
ans++;
set.clear();
}
set.add(s.charAt(i));
}
return ans;
}
public static void main(String[] args)
{
String S = "abacaba" ;
System.out.print(partitionString(S));
}
}
|
Python3
def partitionString(s):
st = set ()
ans = 1
for i in range ( len (s)):
if s[i] in st:
ans + = 1
st.clear()
st.add(s[i])
return ans
S = "abacaba"
print ( "Minimum Number of Substrings with Unique Characters:" , partitionString(S))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int partitionString( string s)
{
HashSet< char > set = new HashSet< char >();
int ans = 1;
for ( int i = 0; i < s.Length; i++) {
if ( set .Contains(s[i])) {
ans++;
set .Clear();
}
set .Add(s[i]);
}
return ans;
}
static public void Main()
{
String S = "abacaba" ;
Console.Write( "Minimum Number of Substrings with Unique Characters: " + partitionString(S));
}
}
|
Javascript
function partitionString(s) {
let st = new Set();
let ans = 1;
for (let i = 0; i < s.length; i++) {
if (st.has(s[i])) {
ans++;
st.clear();
}
st.add(s[i]);
}
return ans;
}
let S = "abacaba" ;
console.log(
"Minimum Number of Substrings with Unique Characters: "
+ partitionString(S));
|
Output
Minimum Number of Substrings with Unique Characters: 4
Time Complexity: O(n) where n is the length of the input string.
Auxiliary Space: O(n) in the worst case This is because we store each character of the input string in the hash set, and in the worst case, all characters of the string are unique.
Efficient Approach: To solve the problem using a Greedy approach follow the below idea:
To solve this problem, we need to keep track of the last occurrence of each character in the string s. Whenever we encounter a repeated character, we know that the current substring contains a character that is repeated, so we need to start a new substring. We can determine the start of the new substring by setting the value of start to the index of the repeated character. We also increased the value of ans to indicate that we have started a new substring.
Below are the steps for the above approach:
- Create an array list of size 26 to store the last index of each character (initially set to -1).
Initialize the starting index of the current substring to 0.
- Initialize the answer variable ans to 1.
- Iterate through the given string s:
- Get the index of the current character in the array by subtracting ‘a’ from it.
- Check if the current character is already present in the current substring by comparing its last index with the starting index of the current substring.
- If it is, increment the answer variable ans and update the starting index of the new substring to the current index.
- Update the last index of the current character in the array with the current index.
- Return the answer variable ans, which gives the minimum number of substrings required.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int partitionString(string s)
{
vector< int > last(26, -1);
int start = 0;
int ans = 1;
for ( int i = 0; i < s.length(); i++) {
int index = s[i] - 'a' ;
if (last[index] >= start) {
ans++;
start = i;
}
last[index] = i;
}
return ans;
}
int main()
{
string S = "abacaba" ;
cout << "Minimum Number of Substrings with Unique "
"Characters: "
<< partitionString(S);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int partitionString(String s)
{
int [] last = new int [ 26 ];
Arrays.fill(last, - 1 );
int start = 0 ;
int ans = 1 ;
for ( int i = 0 ; i < s.length(); i++) {
int index = s.charAt(i) - 'a' ;
if (last[index] >= start) {
ans++;
start = i;
}
last[index] = i;
}
return ans;
}
public static void main(String[] args)
{
String S = "ssssss" ;
System.out.print(partitionString(S));
}
}
|
Python3
def partitionString(s):
last = [ - 1 ] * 26
start = 0
ans = 1
for i in range ( len (s)):
index = ord (s[i]) - ord ( 'a' )
if last[index] > = start:
ans + = 1
start = i
last[index] = i
return ans
if __name__ = = '__main__' :
S = "abacaba"
print ( "Minimum Number of Substrings with Unique Characters: " , partitionString(S))
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static int PartitionString( string s)
{
Dictionary< char , int > last = new Dictionary< char , int >();
int start = 0;
int ans = 1;
for ( int i = 0; i < s.Length; i++)
{
char c = s[i];
if (last.ContainsKey(c) && last >= start)
{
ans++;
start = i;
}
last = i;
}
return ans;
}
public static void Main()
{
string S = "abacaba" ;
Console.WriteLine( "Minimum Number of Substrings with Unique Characters: " + PartitionString(S));
}
}
|
Javascript
function partitionString(s) {
const last = new Array(26).fill(-1);
let start = 0;
let ans = 1;
for (let i = 0; i < s.length; i++) {
const index = s.charCodeAt(i) - 97;
if (last[index] >= start) {
ans++;
start = i;
}
last[index] = i;
}
return ans;
}
const S = "abacaba" ;
console.log(`Minimum Number of Substrings with Unique Characters: ${partitionString(S)}`);
|
Output
Minimum Number of Substrings with Unique Characters: 4
Time Complexity: O(n) where n is the length of the input string.
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...