Maximize count of non overlapping substrings which contains all occurrences of its characters

10 Mar, 2022
Given string str consisting of lowercase letters, the task is to find the maximum number of non-overlapping substrings such that each substring contains all occurrences of its characters from the entire string. If multiple solutions with the same number of substrings exist, then print the one with the minimum total length.
Examples:
Input: str = “abbaccd” Output: bb cc d Explanation: The maximum number of substrings is such that all occurrences of its characters in the string are present. 
The substrings are {{d, bb, cc}, {d, abba, cc}} 
Therefore, the substrings of smallest possible length are {d, bb, cc}. 
Input: str = “adefaddaccc” Output: e f ccc
Approach: The problem can be solved using the Greedy technique. Follow the steps below to solve the problem:
Initialize an array, say res[], to store the required substrings.
Initialize two arrays, say L[] and R[], to store the leftmost and rightmost indices of all possible characters of the given string respectively.
Traverse the string and store the leftmost and rightmost index of all possible characters of the given string.
Traverse the string using the variable i and check if i is the leftmost index of str[i], check if the substring starting from the ith position consisting of all occurrences of str[i] does not overlap with any of the substrings consisting of characters up to str[i -1] or not. If found to be true, then append the current substring into res[].
Finally, print the res[] array.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program to implement// the above approach #include <bits/stdc++.h>using namespace std; // Function to check if substring contains all// occurrences of each character of str or notint checkValid(string str,int i, int L[], int R[]){     // Stores rightmost index of str[i]    int right = R[str[i] - 'a'];     // Traverse the current substring    for (int j = i; j < right; j++){         // If leftmost index of str[j]        // less than i        if (L[str[j] - 'a'] < i)            return -1;         // Update right           right = max(right, R[str[j] - 'a']);    }      return right; }     // Function to find maximum number of substring// that satisfy the conditionvector<string> maxcntOfSubstrings(string str) {           // Stores all substrings that    // satisfy the condition     vector<string> res;          // Stores length of str    int n = str.length();          // Stores leftmost index    // of each character    int L[26];          // Stores rightmost index    // of each character    int R[26];          // Initialize L[] and R[]    for(int i = 0; i <26; i++) {                 // Initialize L[i]        // and R[i]        L[i] = R[i] = -1;    }          // Traverse the string    for (int i = 0; i < n; i++) {                  // If str[i] not        // already occurred        if (L[str[i] - 'a'] == -1) {                                      // Update leftmost index            // of str[i]            L[str[i] - 'a'] = i;                         }                  // Update rightmost index        // of str[i]        R[str[i]-'a'] = i;    }          // Stores rightmost index of last    // substring inserted into res[]    int right = -1;          // Traverse the string    for (int i = 0; i < n; i++) {                  // If i is leftmost index of str[i]        if (i == L[str[i] - 'a']) {                          // Check if a new substring starting            // from i satisfies the conditions or not            int new_right = checkValid(str, i,                                        L, R);                          // If the substring starting from i            // satisfies the conditions            if(new_right != -1){                 // Stores the substring starting from                // i that satisfy the condition                string sub = str.substr(i,                        new_right - i + 1);                                                               // If the substring overlaps                // with another substring                            if(new_right < right){                     // Stores sub to the last                    // of res                    res.back() = sub;                }                else {                                          // If sub not overlaps to                    // other string then  append                    // sub to the end of res                    res.push_back(sub);                }                                  // Update right                right = new_right;            }        }    }        return res;}  // Driver Codeint main(){    string str = "abbaccd";         // Stores maximum number of substring    // that satisfy the condition    vector<string> res      = maxcntOfSubstrings(str);           // Print all substring    for(auto sub : res) {        cout<<sub<<" ";    }}    
// Java program to implement// the above approachimport java.util.*; class GFG{ // Function to check if subString contains all// occurrences of each character of str or notstatic int checkValid(String str, int i,                         int L[], int R[]){         // Stores rightmost index of str.charAt(i)    int right = R[(int)(str.charAt(i)) - 97];     // Traverse the current subString    for(int j = i; j < right; j++)    {                 // If leftmost index of str[j]        // less than i        if (L[(int)(str.charAt(j)) - 97] < i)            return -1;         // Update right           right = Math.max(right,                         R[(int)(str.charAt(j)) - 97]);    }    return right;}  // Function to find maximum number of subString// that satisfy the conditionstatic Vector<String> maxcntOfSubStrings(String str){         // Stores all subStrings that    // satisfy the condition     Vector<String> res = new Vector<String>();         // Stores length of str    int n = str.length();         // Stores leftmost index    // of each character    int []L = new int[26];         // Stores rightmost index    // of each character    int []R = new int[26];         // Initialize L[] and R[]    for(int i = 0; i < 26; i++)    {                 // Initialize L[i]        // and R[i]        L[i] = R[i] = -1;    }         // Traverse the String    for(int i = 0; i < n; i++)    {                 // If str.charAt(i) not        // already occurred        if (L[(int)(str.charAt(i)) - 97] == -1)        {                         // Update leftmost index            // of str.charAt(i)            L[(int)(str.charAt(i)) - 97] = i;        }                 // Update rightmost index        // of str.charAt(i)        R[(int)(str.charAt(i)) - 97] = i;    }         // Stores rightmost index of last    // subString inserted into res[]    int right = -1;         // Traverse the String    for(int i = 0; i < n; i++)    {                 // If i is leftmost index of str.charAt(i)        if (i == L[(int)(str.charAt(i)) - 97])        {                         // Check if a new subString starting            // from i satisfies the conditions or not            int new_right = checkValid(str, i, L, R);                         // If the subString starting from i            // satisfies the conditions            if (new_right != -1)            {                                 // Stores the subString starting from                // i that satisfy the condition                String sub = str.substring(i,                                           new_right + 1);                                 // If the subString overlaps                // with another subString                            if(new_right < right)                {                                         // Stores sub to the last                    // of res                    res.set(res.size() - 1, sub);                }                else                {                                         // If sub not overlaps to                    // other String then  append                    // sub to the end of res                    res.add(sub);                }                                 // Update right                right = new_right;            }        }    }    return res;} // Driver Codepublic static void main(String args[]){    String str = "abbaccd";         // Stores maximum number of subString    // that satisfy the condition    Vector<String> res = maxcntOfSubStrings(str);           // Print all subString    for(int i = 0; i < res.size(); i++)    {        System.out.print(res.get(i) + " ");    }}} // This code is contributed by SURENDRA_GANGWAR
# Python3 program to implement# the above approach # Function to check if substring contains# all occurrences of each character# of str or notdef checkValid(str,i, L, R):     # Stores rightmost index    # of str[i]    right = R[ord(str[i]) -              ord('a')]     # Traverse the current sub    for j in range(i, right):         # If leftmost index of str[j]        # less than i        if (L[ord(str[j]) -              ord('a')] < i):            return -1         # Update right        right = max(right, R[ord(str[j]) -                             ord('a')])     return right # Function to find maximum# number of substring that satisfy# the conditiondef maxcntOfSubstrings(str):       # Stores all substrings that    # satisfy the condition    res = []     # Stores length of str    n = len(str)     # Stores leftmost index    # of each character    L = [-1] * 26     # Stores rightmost index    # of each character    R = [-1] * 26     for j, i in enumerate(str):        x = ord(i) - ord('a')                 # If str[i] not         # already occurred        if L[x] == -1:                       # Update leftmost index            # of str[i]                        L[x] = j         # Update rightmost index         # of str[i]                    R[x] = j     # Stores rightmost index of    # last substring inserted    # into res[]     right = -1     for j, i in enumerate(str):        x = ord(i) - ord('a')         # If i is leftmost index        # of str[i]        if j == L[x]:                       # Check if a new substring            # starting from i satisfies            # the conditions or not                        new_right = checkValid(str, j,                                   L, R)             # If the substring starting            # from i satisfies the conditions            if new_right != -1:                 # Stores the substring starting                # from i that satisfy the condition                sub = str[j : new_right + 1]                 # If the substring overlaps                # with another substring                if new_right < right:                    res[-1] = sub                else:                                       # If sub not overlaps to                     # other string then  append                    # sub to the end of res                    res.append(sub)                right = new_right     return res # Driver Codeif __name__ == '__main__':       str = "abbaccd"     # Stores maximum number of sub    # that satisfy the condition    res = maxcntOfSubstrings(str)     # Print sub    for sub in res:        print(sub, end = " ") # This code is contributed by Mohit Kumar 29
// C# program to implement// the above approachusing System;using System.Collections.Generic;class GFG {         // Function to check if substring contains all    // occurrences of each character of str or not    static int checkValid(string str,int i, int[] L, int[] R)    {              // Stores rightmost index of str[i]        int right = R[str[i] - 'a'];              // Traverse the current substring        for (int j = i; j < right; j++){                  // If leftmost index of str[j]            // less than i            if (L[str[j] - 'a'] < i)                return -1;                  // Update right               right = Math.Max(right, R[str[j] - 'a']);        }               return right;     }                // Function to find maximum number of substring    // that satisfy the condition    static List<string> maxcntOfSubstrings(string str)    {                    // Stores all substrings that        // satisfy the condition        List<string> res = new List<string>();                  // Stores length of str        int n = str.Length;                  // Stores leftmost index        // of each character        int[] L = new int[26];                    // Stores rightmost index        // of each character        int[] R = new int[26];                      // Initialize L[] and R[]        for(int i = 0; i <26; i++)        {                          // Initialize L[i]            // and R[i]            L[i] = R[i] = -1;        }                        // Traverse the string        for (int i = 0; i < n; i++)        {                          // If str[i] not            // already occurred            if (L[str[i] - 'a'] == -1)            {                                  // Update leftmost index                // of str[i]                L[str[i] - 'a'] = i;                   }                          // Update rightmost index            // of str[i]            R[str[i]-'a'] = i;        }                 // Stores rightmost index of last        // substring inserted into res[]        int right = -1;                  // Traverse the string        for (int i = 0; i < n; i++)        {                  // If i is leftmost index of str[i]            if (i == L[str[i] - 'a'])            {                                  // Check if a new substring starting                // from i satisfies the conditions or not                int new_right = checkValid(str, i, L, R);                                  // If the substring starting from i                // satisfies the conditions                if(new_right != -1){                          // Stores the substring starting from                    // i that satisfy the condition                    string sub = str.Substring(i, new_right - i + 1);                                                       // If the substring overlaps                    // with another substring                                if(new_right < right){                              // Stores sub to the last                        // of res                        res[res.Count - 1] = sub;                    }                    else {                                                  // If sub not overlaps to                        // other string then  append                        // sub to the end of res                        res.Add(sub);                    }                                          // Update right                    right = new_right;                }            }        }            return res;    }   // Driver code  static void Main() {        string str = "abbaccd";              // Stores maximum number of substring        // that satisfy the condition        List<string> res = maxcntOfSubstrings(str);                    // Print all substring        foreach(string sub in res) {            Console.Write(sub + " ");        }  }} // This code is contributed by divyeshrabadiya
<script>      // JavaScript program to implement      // the above approach      // Function to check if substring contains all      // occurrences of each character of str or not      function checkValid(str, i, L, R) {        // Stores rightmost index of str[i]        var right = R[str[i].charCodeAt(0) - "a".charCodeAt(0)];         // Traverse the current substring        for (var j = i; j < right; j++) {          // If leftmost index of str[j]          // less than i          if (L[str[j].charCodeAt(0) - "a".charCodeAt(0)] < i)              return -1;           // Update right          right = Math.max(right, R[str[j].charCodeAt(0) - "a".charCodeAt(0)]);        }         return right;      }       // Function to find maximum number of substring      // that satisfy the condition      function maxcntOfSubstrings(str) {        // Stores all substrings that        // satisfy the condition        var res = [];         // Stores length of str        var n = str.length;         // Stores leftmost index        // of each character        var L = new Array(26).fill(-1);         // Stores rightmost index        // of each character        var R = new Array(26).fill(-1);         // Traverse the string        for (var i = 0; i < n; i++) {          var x = str[i].charCodeAt(0) - "a".charCodeAt(0);          // If str[i] not          // already occurred          if (L[x] === -1) {            // Update leftmost index            // of str[i]            L[x] = i;          }           // Update rightmost index          // of str[i]          R[x] = i;        }         // Stores rightmost index of last        // substring inserted into res[]        var right = -1;         // Traverse the string        for (var i = 0; i < n; i++) {          var x = str[i].charCodeAt(0) - "a".charCodeAt(0);           // If i is leftmost index of str[i]          if (i === L[x]) {            // Check if a new substring starting            // from i satisfies the conditions or not            var new_right = checkValid(str, i, L, R);             // If the substring starting from i            // satisfies the conditions            if (new_right !== -1) {              // Stores the substring starting from              // i that satisfy the condition              var sub = str.substring(i, new_right + 1);               // If the substring overlaps              // with another substring              if (new_right < right) {                // Stores sub to the last                // of res                res[res.length - 1] = sub;              }              else {                // If sub not overlaps to                // other string then append                // sub to the end of res                res.push(sub);              }               // Update right              right = new_right;            }          }        }        return res;      }       // Driver code      var str = "abbaccd";       // Stores maximum number of substring      // that satisfy the condition      var res = maxcntOfSubstrings(str);       // Print all substring      for (const sub of res) {        document.write(sub + " ");      }</script>
bb cc d
 
Time Complexity: O(N * 26) Auxiliary Space: O(26)
mohit kumar 29
SURENDRA_GANGWAR
divyeshrabadiya07
rdtank
akshaysingh98088
simmytarika5
surinderdawra388
frequency-counting
substring
Strings
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Check for Balanced Brackets in an expression (well-formedness) using Stack
Different Methods to Reverse a String in C++
Python program to check if a string is palindrome or not
KMP Algorithm for Pattern Searching
Longest Palindromic Substring | Set 1
Top 50 String Coding Problems for Interviews
What is Data Structure: Types, Classifications and Applications
Length of the longest substring without repeating characters
Convert string to char array in C++
Reverse words in a given string