📌  相关文章
📜  最大化包含所有出现的字符的非重叠子串的计数

📅  最后修改于: 2021-09-07 04:06:08             🧑  作者: Mango

给定由小写字母组成的字符串str ,任务是找到最大数量的非重叠子字符串,使得每个子字符串包含整个字符串中所有出现的字符。如果存在多个具有相同子串数的解决方案,则打印总长度最小的解决方案。

例子:

方法:该问题可以使用贪心技术解决。请按照以下步骤解决问题:

  • 初始化一个数组,比如res[] ,以存储所需的子字符串。
  • 初始化两个数组,比如L[]R[] ,分别存储给定字符串的所有可能字符的最左边和最右边的索引。
  • 遍历字符串并存储给定字符串的所有可能字符的最左边和最右边的索引。
  • 使用变量i遍历字符串并检查i是否是str[i]的最左边索引,检查从第 i位置开始的由所有出现的str[i]组成的子字符串是否与由以下组成的任何子字符串不重叠不超过str[i -1] 的字符。如果发现为真,则将当前子字符串附加到res[] 中
  • 最后,打印res[]数组。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to check if substring contains all
// occurrences of each character of str or not
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 = max(right, R[str[j] - 'a']);
    }
  
    return right;
 }
  
  
 
// Function to find maximum number of substring
// that satisfy the condition
vector maxcntOfSubstrings(string str) {
      
 
    // Stores all substrings that
    // satisfy the condition 
    vector 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 Code
int main()
{
    string str = "abbaccd";
     
    // Stores maximum number of substring
    // that satisfy the condition
    vector res
      = maxcntOfSubstrings(str);
       
    // Print all substring
    for(auto sub : res) {
        cout<


Java
// Java program to implement
// the above approach
import java.util.*;
 
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.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 condition
static Vector maxcntOfSubStrings(String str)
{
     
    // Stores all subStrings that
    // satisfy the condition 
    Vector res = new Vector();
     
    // 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 Code
public static void main(String args[])
{
    String str = "abbaccd";
     
    // Stores maximum number of subString
    // that satisfy the condition
    Vector 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
# Python3 program to implement
# the above approach
 
# Function to check if subcontains
# all occurrences of each character
# of str or not
def 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 sub that satisfy
# the condition
def 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 Code
if __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#
// C# program to implement
// the above approach
using 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 maxcntOfSubstrings(string str)
    {
            
        // Stores all substrings that
        // satisfy the condition
        List res = new List();
          
        // 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 res = maxcntOfSubstrings(str);
            
        // Print all substring
        foreach(string sub in res) {
            Console.Write(sub + " ");
        }
  }
}
 
// This code is contributed by divyeshrabadiya


Javascript


输出:
bb cc d

时间复杂度: O(N * 26)
辅助空间: O(26)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live