Maximize String Partitions with No Common Characters
Last Updated :
27 Apr, 2025
Given a string s
consisting of lowercase English letters, partition s
into the maximum number of substrings such that no two substrings share a common character. Return the total number of such substrings.
Examples:
Input: s = "acbbcc"
Output: 2
Explanation: "a" and "cbbcc" are two substrings that do not share any characters between them.
Input: str = “aaa”
Output: 1
Explanation:
Since the string consists of a single character, no partition can be performed.
Input: s = "ababcbacadefegdehijhklij"
Output: 3
Explanation: "ababcbaca", "defegde" and "hijhklij" are three substrings that do not share any characters between them..
[Naive Approach] Check Character Repetition at Every Point - O(n^2) Time and O(1) Space
We run two nested loops. The outer loop traverses through all indexes and keeps track of all the visited characters. The inner loop checks if the any future character matches with the visited characters. If no future character matches, we increment the partition count.
C++
#include <iostream>
#include <string>
using namespace std;
int MaxPartition(string &s)
{
int n = s.size();
int partitions = 0;
bool visited[26] = {0};
for (int i = 0; i < n; ++i)
{
visited[s[i] - 'a'] = true;
bool isPartition = true;
// Check if we have reached a
// point after which no previously
// seen character appears
for (int j = i + 1; j < n; ++j)
{
if (visited[s[j] - 'a'])
{
isPartition = false;
break;
}
}
// If we reached a parition point
if (isPartition)
partitions++;
}
return partitions;
}
int main()
{
string s = "ababcbacadefegdehijhklij";
cout << MaxPartition(s) << endl;
return 0;
}
Java
public class Main {
public static int maxPartition(String s) {
int n = s.length();
int partitions = 0;
boolean[] visited = new boolean[26];
for (int i = 0; i < n; ++i) {
visited[s.charAt(i) - 'a'] = true;
boolean isPartition = true;
// Check if we have reached a
// point after which no previously
// seen character appears
for (int j = i + 1; j < n; ++j) {
if (visited[s.charAt(j) - 'a']) {
isPartition = false;
break;
}
}
// If we reached a partition point
if (isPartition)
partitions++;
}
return partitions;
}
public static void main(String[] args) {
String s = "ababcbacadefegdehijhklij";
System.out.println(maxPartition(s));
}
}
Python
def max_partition(s):
n = len(s)
partitions = 0
visited = [False] * 26
for i in range(n):
visited[ord(s[i]) - ord('a')] = True
is_partition = True
# Check if we have reached a
# point after which no previously
# seen character appears
for j in range(i + 1, n):
if visited[ord(s[j]) - ord('a')]:
is_partition = False
break
# If we reached a partition point
if is_partition:
partitions += 1
return partitions
s = "ababcbacadefegdehijhklij"
print(max_partition(s))
C#
using System;
class Program {
public static int MaxPartition(string s) {
int n = s.Length;
int partitions = 0;
bool[] visited = new bool[26];
for (int i = 0; i < n; ++i) {
visited[s[i] - 'a'] = true;
bool isPartition = true;
// Check if we have reached a
// point after which no previously
// seen character appears
for (int j = i + 1; j < n; ++j) {
if (visited[s[j] - 'a']) {
isPartition = false;
break;
}
}
// If we reached a partition point
if (isPartition)
partitions++;
}
return partitions;
}
public static void Main() {
string s = "ababcbacadefegdehijhklij";
Console.WriteLine(MaxPartition(s));
}
}
JavaScript
function maxPartition(s) {
const n = s.length;
let partitions = 0;
const visited = new Array(26).fill(false);
for (let i = 0; i < n; ++i) {
visited[s.charCodeAt(i) - 'a'.charCodeAt(0)] = true;
let isPartition = true;
// Check if we have reached a
// point after which no previously
// seen character appears
for (let j = i + 1; j < n; ++j) {
if (visited[s.charCodeAt(j) - 'a'.charCodeAt(0)]) {
isPartition = false;
break;
}
}
// If we reached a partition point
if (isPartition)
partitions++;
}
return partitions;
}
const s = "ababcbacadefegdehijhklij";
console.log(maxPartition(s));
[Expected Approach 1] Using Greedy approach and array - O(n) Time and O(1) Space
The idea is to first initialize an array last
of size 26 (to represent all lowercase English letters) with -1
, which is used to store the last occurrence index of each character in the string.
Once we get last occurrence of each character, we traverse through the string again and keep track of the farthest last index so far. At any point, if current character's index is equal to the farthest index of last index so far, it means after this index, no previously see character would appear, so we have a partition just after the current index.
To implement the above logic, we initialize two variables:
cnt
to count the number of partitions a
to track the farthest last occurrence of any character in the current substring.
Iterates through the string again, updating a
to reflect the maximum last occurrence index encountered so far. If a
matches the current index i
, it means the substring can be closed at this position, forming a valid partition. The partition count (cnt
) is then incremented.
This process continues until the end of the string is reached, return cnt(maximum number of partition).
C++
// C++ program to split the string
// to maximum number of substring
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum number of substrings
// such that there is no common charcater between them
int maxPartitions(string &s) {
// Vector to store the last occurrence
// of each character in the string
vector<int> last(26, -1);
// Traverse the string in reverse to record
// the last position of each character
for (int i = 0; i < s.size(); i++)
last[s[i] - 'a'] = i;
// count the number of partitions
int cnt = 0;
// To track the farthest last occurrence seen
int a = -1;
for (int i = 0; i < s.size(); i++)
{
a = max(last[s[i] - 'a'], a);
// If the current index matches the
// farthest occurrence, form a partition
if (a == i)
cnt++;
}
return cnt;
}
int main()
{
string s = "acbbcc";
cout << maxPartitions(s);
}
Java
// Java program to split the string
import java.util.HashMap;
public class Main {
// Function to find the maximum number of substrings
// such that there is no common character between them
public static int maxPartitions(String s) {
// HashMap to store the last occurrence
// of each character in the string
int[] last = new int[26];
for (int i = 0; i < last.length; i++) {
last[i] = -1;
}
// Traverse the string to record
// the last position of each character
for (int i = 0; i < s.length(); i++)
last[s.charAt(i) - 'a'] = i;
// count the number of partitions
int cnt = 0;
// To track the farthest last occurrence seen
int a = -1;
for (int i = 0; i < s.length(); i++) {
a = Math.max(last[s.charAt(i) - 'a'], a);
// If the current index matches the
// farthest occurrence, form a partition
if (a == i)
cnt++;
}
return cnt;
}
public static void main(String[] args) {
String s = "acbbcc";
System.out.println(maxPartitions(s));
}
}
Python
# Python program to split the string
def max_partitions(s):
# List to store the last occurrence
# of each character in the string
last = [-1] * 26
# Traverse the string to record
# the last position of each character
for i in range(len(s)):
last[ord(s[i]) - ord('a')] = i
# count the number of partitions
cnt = 0
# To track the farthest last occurrence seen
a = -1
for i in range(len(s)):
a = max(last[ord(s[i]) - ord('a')], a)
# If the current index matches the
# farthest occurrence, form a partition
if a == i:
cnt += 1
return cnt
s = 'acbbcc'
print(max_partitions(s))
C#
// C# program to split the string
using System;
class Program {
// Function to find the maximum number of substrings
// such that there is no common character between them
public static int MaxPartitions(string s) {
// Array to store the last occurrence
// of each character in the string
int[] last = new int[26];
Array.Fill(last, -1);
// Traverse the string to record
// the last position of each character
for (int i = 0; i < s.Length; i++)
last[s[i] - 'a'] = i;
// count the number of partitions
int cnt = 0;
// To track the farthest last occurrence seen
int a = -1;
for (int i = 0; i < s.Length; i++) {
a = Math.Max(last[s[i] - 'a'], a);
// If the current index matches the
// farthest occurrence, form a partition
if (a == i)
cnt++;
}
return cnt;
}
static void Main() {
string s = "acbbcc";
Console.WriteLine(MaxPartitions(s));
}
}
JavaScript
// JavaScript program to split the string
function maxPartitions(s) {
// Array to store the last occurrence
// of each character in the string
let last = new Array(26).fill(-1);
// Traverse the string to record
// the last position of each character
for (let i = 0; i < s.length; i++)
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
// count the number of partitions
let cnt = 0;
// To track the farthest last occurrence seen
let a = -1;
for (let i = 0; i < s.length; i++) {
a = Math.max(last[s.charCodeAt(i) - 'a'.charCodeAt(0)], a);
// If the current index matches the
// farthest occurrence, form a partition
if (a === i)
cnt++;
}
return cnt;
}
let s = 'acbbcc';
console.log(maxPartitions(s));
[Expected Approach 2] By merging intervals - O(n) Time and O(1) Space.
The main idea is to track first and last occurrence of character and treat them as intervals (first occ, last occ).
Once we have these intervals, we need to merge overlapping ones. If two intervals overlap, it means that the characters in those intervals must be part of the same substring. The merging process ensures that we are not splitting a character across multiple partitions.
After merging all overlapping intervals, the number of separate intervals left gives the desired result.
C++
// C++ program to split the string
// to maximum number of substring
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum number of substrings
// such that there is no common charcater between them
int maxPartitions(string &s) {
vector<int> first(26, -1), last(26, -1);
for (int i = 0; i < s.size(); i++) {
if (first[s[i] - 'a'] == -1)
first[s[i] - 'a'] = i;
last[s[i] - 'a'] = i;
}
int count = 0;
int end = 0;
for (int i = 0; i < s.size(); i++) {
// Expand interval
end = max(end, last[s[i] - 'a']);
// When we reach the end of a partition
if (i == end) {
// New partition formed
count++;
}
}
return count;
}
int main() {
string s = "acbbcc";
cout<<maxPartitions(s);
}
Java
// Java program to split the string
// to maximum number of substring
import java.util.*;
class GfG {
// Function to find the maximum number of substrings
// such that there is no common character between them
static int maxPartitions(String s) {
// Arrays to store first and last occurrence of each character
int[] first = new int[26], last = new int[26];
Arrays.fill(first, -1);
Arrays.fill(last, -1);
// Find the first and last occurrence of each character
for (int i = 0; i < s.length(); i++) {
if (first[s.charAt(i) - 'a'] == -1)
first[s.charAt(i) - 'a'] = i;
last[s.charAt(i) - 'a'] = i;
}
int count = 0;
int end = 0;
// Iterate through the string to find partitions
for (int i = 0; i < s.length(); i++) {
// Expand interval
end = Math.max(end, last[s.charAt(i) - 'a']);
// When we reach the end of a partition
if (i == end) {
// New partition formed
count++;
}
}
return count;
}
public static void main(String[] args) {
String s = "acbbcc";
System.out.println(maxPartitions(s));
}
}
Python
# Function to find the maximum number of substrings
# such that there is no common character between them
def maxPartitions(s):
# Arrays to store first and last occurrence of each character
first = [-1] * 26
last = [-1] * 26
# Find the first and last occurrence of each character
for i in range(len(s)):
if first[ord(s[i]) - ord('a')] == -1:
first[ord(s[i]) - ord('a')] = i
last[ord(s[i]) - ord('a')] = i
count = 0
end = 0
# Iterate through the string to find partitions
for i in range(len(s)):
# Expand interval
end = max(end, last[ord(s[i]) - ord('a')])
# When we reach the end of a partition
if i == end:
# New partition formed
count += 1
return count
if __name__ == "__main__":
s = "acbbcc"
print(maxPartitions(s))
C#
using System;
class GfG {
// Function to find the maximum number of substrings
// such that there is no common character between them
static int maxPartitions(string s) {
// Arrays to store first and last occurrence of each character
int[] first = new int[26];
int[] last = new int[26];
Array.Fill(first, -1);
Array.Fill(last, -1);
// Find the first and last occurrence of each character
for (int i = 0; i < s.Length; i++) {
if (first[s[i] - 'a'] == -1)
first[s[i] - 'a'] = i;
last[s[i] - 'a'] = i;
}
int count = 0;
int end = 0;
// Iterate through the string to find partitions
for (int i = 0; i < s.Length; i++) {
// Expand interval
end = Math.Max(end, last[s[i] - 'a']);
// When we reach the end of a partition
if (i == end) {
// New partition formed
count++;
}
}
return count;
}
static void Main() {
string s = "acbbcc";
Console.WriteLine(maxPartitions(s));
}
}
JavaScript
// Function to find the maximum number of substrings
// such that there is no common character between them
function maxPartitions(s) {
// Arrays to store first and last occurrence of each character
let first = new Array(26).fill(-1);
let last = new Array(26).fill(-1);
// Find the first and last occurrence of each character
for (let i = 0; i < s.length; i++) {
if (first[s.charCodeAt(i) - 'a'.charCodeAt(0)] === -1) {
first[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
}
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
}
let count = 0;
let end = 0;
// Iterate through the string to find partitions
for (let i = 0; i < s.length; i++) {
// Expand interval
end = Math.max(end, last[s.charCodeAt(i) - 'a'.charCodeAt(0)]);
// When we reach the end of a partition
if (i === end) {
// New partition formed
count++;
}
}
return count;
}
// Driver Code
const s = "acbbcc";
console.log(maxPartitions(s));
Similar Reads
Maximize partitions such that no two substrings have any common character
Given string s of size n, the task is to print the number of substrings formed after maximum possible partitions such that no two substrings have a common character.Examples: Input : s = "ababcbacadefegdehijhklij" Output : 3 Explanation: Partitioning at the index 8 and at 15 produces three substring
1 min read
Split string to get maximum common characters
Given a string S of length, N. Split them into two strings such that the number of common characters between the two strings is maximized and return the maximum number of common characters. Examples: Input: N = 6, S = abccbaOutput: 3Explanation: Splitting two strings as "abc" and "cba" has at most 3
6 min read
Common characters in n strings
Given n strings, find the common characters in all the strings. In simple words, find characters that appear in all the strings and display them in alphabetical order or lexicographical order. Note* we'll be considering that the strings contain lower case letters only. Examples: Input : geeksforgeek
6 min read
Maximize product of lengths of strings having no common characters
Given an array arr[] consisting of N strings, the task is to find the maximum product of the length of the strings arr[i] and arr[j] for all unique pairs (i, j), where the strings arr[i] and arr[j] contain no common characters. Examples: Input: arr[] = {"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}
12 min read
Maximize characters to be removed from string with given condition
Given a string s. The task is to maximize the removal of characters from s. Any character can be removed if at least one of its adjacent characters is the previous letter in the Latin English alphabet. Examples: Input: s = "bacabcab"Output: 4Explanation: Following are the removals that maximize the
6 min read
Longest Common Subsequence with no repeating character
Given two strings s1 and s2, the task is to find the length of the longest common subsequence with no repeating character. Examples: Input: s1= "aabbcc", s2= "aabc"Output: 3Explanation: "aabc" is longest common subsequence but it has two repeating character 'a'.So the required longest common subsequ
10 min read
String Partitioning for Character Equality
Given a string S of size N, the task is to divide the given string into two non-empty strings s1 and s2 such that the number of distinct characters in s1 is equal to s2. Examples: Input: s = "aacaba"Output: 2Explanation: => Dividing s into s1 and s2 as ("aac", "aba"), the left string contains 2 d
7 min read
Maximum Balanced String Partitions
Given a balanced string str of size N with an equal number of L and R, the task is to find a maximum number X, such that a given string can be partitioned into X balanced substring. A string called to be balanced if the number of 'L's in the string equals the number of 'R's. Examples: Input : str =
7 min read
Maximize ascii sum removing K characters in String
Given a string s and an integer K, the task is to remove K characters from the string such that the sum of ASCII (American Standard Code for Information Interchange) values of the remaining characters is maximized. Examples: Input: s = "word", K = 2Output: 233Explanation: We need to remove exactly 2
9 min read
String with maximum number of unique characters
Given an array of strings, the task is to print the string with the maximum number of unique characters.Note: Strings consists of lowercase characters.If multiple strings exists, then print any one of them.Examples: Input: arr[] = ["abc", "geeksforgeeks", "gfg", "code"]Output: "geeksforgeeks" Explan
5 min read