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.
Below is the implementation of the above approach:
C++
// 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
// 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
# 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#
// 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 |
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++
// 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
// 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 |
2
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer Complete Interview Preparation Course.