Given a string str, the task is to find the maximum count of common non-repeating characters that can be obtained by partitioning the given string into two non-empty substrings.
Examples:
Input : str = “aabbca”
Output: 2
Explanation:
Partition the string into two substrings { { str[0], … str[2] }, { str[3], …, str[5] } }
The common non-repeating characters present in both the substrings are { ‘a’, ‘b’}
Therefore, the required output is 2.Input: str = “aaaaaaaaaa”
Output: 1
Naive Approach: The simplest approach to solve this problem is to iterate over the characters of the string and partition the string into two non-empty substrings at every possible indices and count the number of common-repeating characters from the two substrings. Print the maximum count obtained.
Algorithm:
- Define a function named countCommonChar that takes two arguments – an integer index and a string S, and returns an integer value.
- Inside the function, initialize a counter variable cnt to zero.
- Create two sets, ls and rs, to store distinct characters in the left and right substrings respectively.
- Traverse the characters in the string S up to the given index and insert each character into the set ls.
- Traverse the characters in the string S from the given index up to the end of the string and insert each character into the set rs.
- Traverse the distinct characters in the set ls.
- For each character, check if it is present in the set rs. If yes, increment the counter variable cnt.
- Return the value of cnt.
- Define another function named partitionStringWithMaxCom that takes a string S as an argument and returns nothing.
- Inside the function, initialize a variable ans to zero.
- Traverse the characters in the string S from the second character to the second last character.
- For each character, call the function countCommonChar with the current index as the argument and store the returned value in a variable temp.
- Update the value of ans by taking the maximum of the current value of ans and temp.
- Print the value of ans.
- The main function reads the input string, calls the function partitionStringWithMaxCom with the input string as the argument, and returns 0.
Pseudocode:
countCommonChar(ind, S): cnt = 0 ls = set() rs = set() for i = 0 to ind - 1: ls.insert(S[i]) for i = ind to length(S) - 1: rs.insert(S[i]) for v in ls: if rs.count(v): cnt = cnt + 1 return cnt partitionStringWithMaxCom(S): ans = 0 for i = 1 to length(S) - 2: temp = countCommonChar(i, S) ans = max(ans, temp) print ans main(): str = input from user partitionStringWithMaxCom(str) return 0
Below is the implementation of the above approach:
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to count maximum common non-repeating // characters that can be obtained by partitioning // the string into two non-empty substrings int countCommonChar( int ind, string& S)
{ // Stores count of non-repeating characters
// present in both the substrings
int cnt = 0;
// Stores distinct characters
// in left substring
set< char > ls;
// Stores distinct characters
// in right substring
set< char > rs;
// Traverse left substring
for ( int i = 0; i < ind; ++i) {
// Insert S[i] into ls
ls.insert(S[i]);
}
// Traverse right substring
for ( int i = ind; i < S.length();
++i) {
// Insert S[i] into rs
rs.insert(S[i]);
}
// Traverse distinct characters
// of left substring
for ( auto v : ls) {
// If current character is
// present in right substring
if (rs.count(v)) {
// Update cnt
++cnt;
}
}
// Return count
return cnt;
} // Function to partition the string into // two non-empty substrings in all possible ways void partitionStringWithMaxCom(string& S)
{ // Stores maximum common distinct characters
// present in both the substring partitions
int ans = 0;
// Traverse the string
for ( int i = 1; i < S.length(); ++i) {
// Update ans
ans = max(ans,
countCommonChar(i, S));
}
// Print count of maximum common
// non-repeating characters
cout << ans << "\n" ;
} // Driver Code int main()
{ string str = "aabbca" ;
partitionStringWithMaxCom(str);
return 0;
} |
// Java program to implement // the above approach import java.util.*;
class GFG{
// Function to count maximum common non-repeating // characters that can be obtained by partitioning // the String into two non-empty subStrings static int countCommonChar( int ind, String S)
{ // Stores count of non-repeating characters
// present in both the subStrings
int cnt = 0 ;
// Stores distinct characters
// in left subString
HashSet<Character> ls = new HashSet<Character>();
// Stores distinct characters
// in right subString
HashSet<Character> rs = new HashSet<Character>();
// Traverse left subString
for ( int i = 0 ; i < ind; ++i) {
// Insert S[i] into ls
ls.add(S.charAt(i));
}
// Traverse right subString
for ( int i = ind; i < S.length();
++i) {
// Insert S[i] into rs
rs.add(S.charAt(i));
}
// Traverse distinct characters
// of left subString
for ( char v : ls) {
// If current character is
// present in right subString
if (rs.contains(v)) {
// Update cnt
++cnt;
}
}
// Return count
return cnt;
} // Function to partition the String into // two non-empty subStrings in all possible ways static void partitionStringWithMaxCom(String S)
{ // Stores maximum common distinct characters
// present in both the subString partitions
int ans = 0 ;
// Traverse the String
for ( int i = 1 ; i < S.length(); ++i) {
// Update ans
ans = Math.max(ans,
countCommonChar(i, S));
}
// Print count of maximum common
// non-repeating characters
System.out.print(ans+ "\n" );
} // Driver Code public static void main(String[] args)
{ String str = "aabbca" ;
partitionStringWithMaxCom(str);
} } // This code is contributed by 29AjayKumar |
# Python3 program to implement # the above approach # Function to count maximum common # non-repeating characters that can # be obtained by partitioning the # string into two non-empty substrings def countCommonChar(ind, S):
# Stores count of non-repeating
# characters present in both the
# substrings
cnt = 0
# Stores distinct characters
# in left substring
ls = set ()
# Stores distinct characters
# in right substring
rs = set ()
# Traverse left substring
for i in range (ind):
# Insert S[i] into ls
ls.add(S[i])
# Traverse right substring
for i in range (ind, len (S)):
# Insert S[i] into rs
rs.add(S[i])
# Traverse distinct characters
# of left substring
for v in ls:
# If current character is
# present in right substring
if v in rs:
# Update cnt
cnt + = 1
# Return count
return cnt
# Function to partition the string # into two non-empty substrings in # all possible ways def partitionStringWithMaxCom(S):
# Stores maximum common distinct
# characters present in both the
# substring partitions
ans = 0
# Traverse the string
for i in range ( 1 , len (S)):
# Update ans
ans = max (ans, countCommonChar(i, S))
# Print count of maximum common
# non-repeating characters
print (ans)
# Driver Code if __name__ = = "__main__" :
string = "aabbca"
partitionStringWithMaxCom(string)
# This code is contributed by AnkThon |
// C# program to implement // the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to count maximum common non-repeating // characters that can be obtained by partitioning // the String into two non-empty subStrings static int countCommonChar( int ind, String S)
{ // Stores count of non-repeating characters
// present in both the subStrings
int cnt = 0;
// Stores distinct characters
// in left subString
HashSet< char > ls = new HashSet< char >();
// Stores distinct characters
// in right subString
HashSet< char > rs = new HashSet< char >();
// Traverse left subString
for ( int i = 0; i < ind; ++i)
{
// Insert S[i] into ls
ls.Add(S[i]);
}
// Traverse right subString
for ( int i = ind; i < S.Length; ++i)
{
// Insert S[i] into rs
rs.Add(S[i]);
}
// Traverse distinct characters
// of left subString
foreach ( char v in ls)
{
// If current character is
// present in right subString
if (rs.Contains(v))
{
// Update cnt
++cnt;
}
}
// Return count
return cnt;
} // Function to partition the String into // two non-empty subStrings in all possible ways static void partitionStringWithMaxCom(String S)
{ // Stores maximum common distinct characters
// present in both the subString partitions
int ans = 0;
// Traverse the String
for ( int i = 1; i < S.Length; ++i)
{
// Update ans
ans = Math.Max(ans,
countCommonChar(i, S));
}
// Print count of maximum common
// non-repeating characters
Console.Write(ans + "\n" );
} // Driver Code public static void Main(String[] args)
{ String str = "aabbca" ;
partitionStringWithMaxCom(str);
} } // This code is contributed by Amit Katiyar |
<script> // JavaScript program to implement // the above approach // Function to count maximum common non-repeating // characters that can be obtained by partitioning // the string into two non-empty substrings function countCommonChar(ind, S)
{ // Stores count of non-repeating characters
// present in both the substrings
var cnt = 0;
// Stores distinct characters
// in left substring
var ls = new Set();
// Stores distinct characters
// in right substring
var rs = new Set();
// Traverse left substring
for ( var i = 0; i < ind; ++i) {
// Insert S[i] into ls
ls.add(S[i]);
}
// Traverse right substring
for ( var i = ind; i < S.length;
++i) {
// Insert S[i] into rs
rs.add(S[i]);
}
// Traverse distinct characters
// of left substring
ls.forEach(v => {
// If current character is
// present in right substring
if (rs.has(v)) {
// Update cnt
++cnt;
}
});
// Return count
return cnt;
} // Function to partition the string into // two non-empty substrings in all possible ways function partitionStringWithMaxCom(S)
{ // Stores maximum common distinct characters
// present in both the substring partitions
var ans = 0;
// Traverse the string
for ( var i = 1; i < S.length; ++i) {
// Update ans
ans = Math.max(ans,
countCommonChar(i, S));
}
// Print count of maximum common
// non-repeating characters
document.write( ans);
} // Driver Code var str = "aabbca" ;
partitionStringWithMaxCom(str); </script> |
2
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, the idea is to use Hashing and Ordered Set to store the distinct characters of the string in sorted order. Follow the steps below to solve the problem:
- Initialize a variable, say res, to store the maximum count of common distinct characters present in both the substrings by partitioning the string into two substrings.
- Initialize a Map, say mp, to store the frequency of each distinct character of the string.
- Initialize an Ordered Set, say Q, to store the distinct characters of the string in sorted order.
- Iterate over characters of the string and for every ith character, decrement the frequency of str[i] and check if the frequency of mp[str[i]] is equal to 0 or not. If found to be false, then remove str[i] from the Ordered Set.
- Otherwise, insert str[i] in the ordered set and update res = max(res, X), where X is the count of elements in the ordered set.
- Finally, print the value of res.
Below is the implementation of the above approach:
// C++ program to implement // the above approach #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
template < typename T>
using ordered_set = tree<T, null_type, less<T>,
rb_tree_tag, tree_order_statistics_node_update>;
// Function to count maximum common non-repeating // characters that can be obtained by partitioning // the string into two non-empty substrings int countMaxCommonChar(string& S)
{ // Stores distinct characters
// of S in sorted order
ordered_set< char > Q;
// Stores maximum common distinct characters
// present in both the partitions
int res = 0;
// Stores frequency of each
// distinct character n the string S
map< char , int > freq;
// Traverse the string
for ( int i = 0; i < S.length(); i++) {
// Update frequency of S[i]
freq[S[i]]++;
}
// Traverse the string
for ( int i = 0; i < S.length(); i++) {
// Decreasing frequency of S[i]
freq[S[i]]--;
// If the frequency of S[i] is 0
if (!freq[S[i]]) {
// Remove S[i] from Q
Q.erase(S[i]);
}
else {
// Insert S[i] into Q
Q.insert(S[i]);
}
// Stores count of distinct
// characters in Q
int curr = Q.size();
// Update res
res = max(res, curr);
}
cout << res << "\n" ;
} // Driver Code int main()
{ string str = "aabbca" ;
// Function call
countMaxCommonChar(str);
return 0;
} |
// Java program to implement // the above approach import java.util.*;
class GFG{
// Function to count maximum common non-repeating // characters that can be obtained by partitioning // the String into two non-empty subStrings static void countMaxCommonChar( char [] S)
{ // Stores distinct characters
// of S in sorted order
LinkedHashSet<Character> Q = new LinkedHashSet<>();
// Stores maximum common distinct characters
// present in both the partitions
int res = 1 ;
// Stores frequency of each
// distinct character n the String S
HashMap<Character, Integer> freq = new HashMap<>();
// Traverse the String
for ( int i = 0 ; i < S.length; i++)
{
// Update frequency of S[i]
if (freq.containsKey(S[i]))
{
freq.put(S[i], freq.get(S[i]) + 1 );
}
else
{
freq.put(S[i], 1 );
}
}
// Traverse the String
for ( int i = 0 ; i < S.length; i++)
{
// Decreasing frequency of S[i]
if (freq.containsKey(S[i]))
{
freq.put(S[i], freq.get(S[i]) - 1 );
}
// If the frequency of S[i] is 0
if (!freq.containsKey(S[i]))
{
// Remove S[i] from Q
Q.remove(S[i]);
}
else
{
// Insert S[i] into Q
Q.add(S[i]);
}
// Stores count of distinct
// characters in Q
int curr = Q.size() - 1 ;
// Update res
res = Math.max(res, curr);
}
System.out.print(res + "\n" );
} // Driver Code public static void main(String[] args)
{ String str = "aabbca" ;
// Function call
countMaxCommonChar(str.toCharArray());
} } // This code is contributed by aashish1995 |
# Python program to implement the above approach from collections import Counter
from sortedcontainers import SortedSet
# Function to count maximum common non-repeating # characters that can be obtained by partitioning # the string into two non-empty substrings def countMaxCommonChar(S):
# Stores distinct characters
# of S in sorted order
Q = SortedSet()
# Stores maximum common distinct characters
# present in both the partitions
res = 0
# Stores frequency of each
# distinct character n the string S
freq = Counter(S)
# Traverse the string
for i in range ( len (S)):
# Decreasing frequency of S[i]
freq[S[i]] - = 1
# If the frequency of S[i] is 0
if freq[S[i]] = = 0 :
# Remove S[i] from Q
Q.discard(S[i])
else :
# Insert S[i] into Q
Q.add(S[i])
# Stores count of distinct
# characters in Q
curr = len (Q)
# Update res
res = max (res, curr)
print (res)
# Driver Code if __name__ = = '__main__' :
str = "aabbca"
# Function call
countMaxCommonChar( str )
# Contributed by adityasha4x71 |
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
// C# program to implement // the above approach class HelloWorld {
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the String into two non-empty subStrings
public static void countMaxCommonChar( char [] S)
{
// Stores distinct characters
// of S in sorted order
SortedSet< char > Q = new SortedSet< char >();
// Stores maximum common distinct characters
// present in both the partitions
int res = 1;
// Stores frequency of each
// distinct character n the String S
Dictionary < char , int > freq = new Dictionary < char , int > ();
// Traverse the String
for ( int i = 0; i < S.Length; i++)
{
// Update frequency of S[i]
if (freq.ContainsKey(S[i]) == true )
{
freq[S[i]] = freq[S[i]] + 1;
}
else
{
freq[S[i]] = 1;
}
}
// Traverse the String
for ( int i = 0; i < S.Length; i++)
{
// Decreasing frequency of S[i]
if (freq.ContainsKey(S[i]))
{
freq[S[i]] = freq[S[i]] - 1;
}
// If the frequency of S[i] is 0
if (!freq.ContainsKey(S[i]))
{
// Remove S[i] from Q
Q.Remove(S[i]);
}
else
{
// Insert S[i] into Q
Q.Add(S[i]);
}
// Stores count of distinct
// characters in Q
int curr = Q.Count - 1;
// Update res
res = Math.Max(res, curr);
}
Console.Write(res);
}
static void Main() {
string str = "aabbca" ;
// Function call
countMaxCommonChar(str.ToCharArray());
}
} // The code is contributed by Arushi Jindal. |
// Javascript program to implement // the above approach // Function to count maximum common non-repeating // characters that can be obtained by partitioning // the string into two non-empty substrings function countMaxCommonChar(S) {
// Stores distinct characters
// of S in sorted order
let Q = new Set();
// Stores maximum common distinct characters
// present in both the partitions
let res = 0;
// Stores frequency of each
// distinct character n the string S
let freq = new Map();
// Traverse the string
for (let i = 0; i < S.length; i++) {
// Decreasing frequency of S[i]
if (freq.has(S[i])) {
freq.set(S[i], freq.get(S[i]) - 1);
} else {
freq.set(S[i], 1);
}
// If the frequency of S[i] is 0
if (freq.get(S[i]) === 0) {
// Remove S[i] from Q
Q. delete (S[i]);
} else {
// Insert S[i] into Q
Q.add(S[i]);
}
// Stores count of distinct
// characters in Q
let curr = Q.size;
// Update res
res = Math.max(res, curr);
}
console.log(res);
} // Driver Code let str = "aabbca" ;
// Function call
countMaxCommonChar(str);
|
2
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)