Open In App

Partition string into two substrings having maximum number of common non-repeating characters

Improve
Improve
Like Article
Like
Save
Share
Report

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:
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:

  1. Define a function named countCommonChar that takes two arguments – an integer index and a string S, and returns an integer value.
  2. Inside the function, initialize a counter variable cnt to zero.
  3. Create two sets, ls and rs, to store distinct characters in the left and right substrings respectively.
  4. Traverse the characters in the string S up to the given index and insert each character into the set ls.
  5. 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.
  6. Traverse the distinct characters in the set ls.
  7. For each character, check if it is present in the set rs. If yes, increment the counter variable cnt.
  8. Return the value of cnt.
  9. Define another function named partitionStringWithMaxCom that takes a string S as an argument and returns nothing.
  10. Inside the function, initialize a variable ans to zero.
  11. Traverse the characters in the string S from the second character to the second last character.
  12. For each character, call the function countCommonChar with the current index as the argument and store the returned value in a variable temp.
  13. Update the value of ans by taking the maximum of the current value of ans and temp.
  14. Print the value of ans.
  15. 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++




// 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


Javascript




<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>


Output

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


Python3




# 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


C#




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




// 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);


Output

2

Time Complexity: O(N * log(N)) 
Auxiliary Space: O(N)



Last Updated : 18 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads