📌  相关文章
📜  在给定的约束下,从字符串删除最少的字符以将其分成三个子字符串

📅  最后修改于: 2021-04-24 19:49:12             🧑  作者: Mango

给定一个由小写字母组成的字符串str ,任务是从给定的字符串删除最少的字符,以便该字符串可以分为3个子字符串str1str2str3 ,以便每个子字符串可以为空或仅包含字符‘a’分别为“ b”“ c”
例子:

方法:此问题可以使用贪婪方法解决。我们将使用三个前缀数组来构成字符‘a’,’b’和’c’的前缀数组。每个前缀数组将分别在任何索引i处存储字母“ a”,“ b”和“ c”的计数。步骤如下:

  1. 创建三个前缀数组为:
    • pre a [i]表示长度为i的前缀中字母“ a”的计数。
    • pref b [i]表示长度为i的前缀中字母“ b”的计数。
    • pref c [i]表示长度为i的前缀中字母“ c”的计数。
  2. 为了删除最小数量的字符,结果字符串应为最大大小。
  3. 这个想法是在字符串0中固定ij的两个位置。一世 ? j≤ N ,以便将字符串分成所有可能的长度的三个部分,并执行以下操作:
    • 从前缀(以i结尾)中删除除“ a”以外所有字符,这将是字符串str1
    • 从后缀j中删除所有不包含‘c’的字符,其后缀为j3 ,即字符串str3
    • 删除除位置i和j之间的‘b’以外所有字符,这将是字符串str2
  4. 因此,结果字符串的总长度由下式给出:
  5. 从给定字符串str的长度中减去结果字符串的长度,以删除要删除的最少字符。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function that counts minimum
// character that must be removed
void min_remove(string str)
{
    // Length of string
    int N = str.length();
  
    // Create prefix array
    int prefix_a[N + 1];
    int prefix_b[N + 1];
    int prefix_c[N + 1];
  
    // Initialize first position
    prefix_a[0] = 0;
    prefix_b[0] = 0;
    prefix_c[0] = 0;
  
    // Fill prefix array
    for (int i = 1; i <= N; i++) {
        prefix_a[i]
            = prefix_a[i - 1]
              + (str[i - 1] == 'a');
  
        prefix_b[i]
            = prefix_b[i - 1]
              + (str[i - 1] == 'b');
  
        prefix_c[i]
            = prefix_c[i - 1]
              + (str[i - 1] == 'c');
    }
  
    // Initialise maxi
    int maxi = INT_MIN;
  
    // Check all the possibilities by
    // putting i and j at different
    // position & find maximum among them
    for (int i = 0; i <= N; i++) {
  
        for (int j = i; j <= N; j++) {
  
            maxi = max(maxi,
                       (prefix_a[i]
                        + (prefix_b[j]
                           - prefix_b[i])
                        + (prefix_c[N]
                           - prefix_c[j])));
        }
    }
  
    // Print the characters to be removed
    cout << (N - maxi) << endl;
}
  
// Driver Code
int main()
{
    // Given String
    string str = "aaaabaaxccac";
  
    // Function Call
    min_remove(str);
  
    return 0;
}


Java
// Java program for the above approach 
class GFG{
      
// Function that counts minimum 
// character that must be removed 
static void min_remove(String str) 
{ 
      
    // Length of string 
    int N = str.length(); 
  
    // Create prefix array 
    int []prefix_a = new int[N + 1]; 
    int []prefix_b = new int[N + 1]; 
    int []prefix_c = new int[N + 1]; 
  
    // Initialize first position 
    prefix_a[0] = 0; 
    prefix_b[0] = 0; 
    prefix_c[0] = 0; 
  
    // Fill prefix array 
    for(int i = 1; i <= N; i++)
    { 
        prefix_a[i] = prefix_a[i - 1] + 
                     (int)((str.charAt(
                            i - 1) == 'a') ? 1 : 0); 
  
        prefix_b[i] = prefix_b[i - 1] +
                      (int)((str.charAt(i - 1) ==
                                     'b') ? 1 : 0); 
  
        prefix_c[i] = prefix_c[i - 1] + 
                      (int)((str.charAt(i - 1) ==
                                     'c') ? 1 : 0); 
    } 
  
    // Initialise maxi 
    int maxi = Integer.MIN_VALUE; 
  
    // Check all the possibilities by 
    // putting i and j at different 
    // position & find maximum among them 
    for(int i = 0; i <= N; i++)
    { 
        for(int j = i; j <= N; j++) 
        { 
            maxi = Math.max(maxi, (prefix_a[i] +
                                  (prefix_b[j] -
                                   prefix_b[i]) +
                                  (prefix_c[N] -
                                   prefix_c[j]))); 
        } 
    } 
  
    // Print the characters to be removed 
    System.out.println((N - maxi)); 
} 
  
// Driver Code 
public static void main(String []args) 
{ 
      
    // Given String 
    String str = "aaaabaaxccac"; 
  
    // Function call 
    min_remove(str); 
} 
}
  
// This code is contributed by grand_master


Python3
# Python 3 program for the above approach
import sys 
  
# Function that counts minimum
# character that must be removed
def min_remove(st):
  
    # Length of string
    N = len(st)
  
    # Create prefix array
    prefix_a = [0]*(N + 1)
    prefix_b = [0]*(N + 1)
    prefix_c = [0]*(N + 1)
  
    # Initialize first position
    prefix_a[0] = 0
    prefix_b[0] = 0
    prefix_c[0] = 0
  
    # Fill prefix array
    for i in range(1, N + 1):
          
        if (st[i - 1] == 'a'):
            prefix_a[i] = (prefix_a[i - 1] + 1)
        else:
            prefix_a[i] = prefix_a[i - 1]
  
        if (st[i - 1] == 'b'):
            prefix_b[i] = (prefix_b[i - 1] + 1)
        else:
            prefix_b[i]= prefix_b[i - 1]
  
        if (st[i - 1] == 'c'):
            prefix_c[i] = (prefix_c[i - 1] + 1)
        else:
            prefix_c[i] = prefix_c[i - 1]
      
    # Initialise maxi
    maxi = -sys.maxsize -1;
  
    # Check all the possibilities by
    # putting i and j at different
    # position & find maximum among them
    for i in range( N + 1):
        for j in range(i, N + 1):
            maxi = max(maxi,
                      (prefix_a[i] + 
                      (prefix_b[j] - 
                       prefix_b[i]) + 
                      (prefix_c[N] -
                       prefix_c[j])))
  
    # Print the characters to be removed
    print((N - maxi))
  
# Driver Code
if __name__ == "__main__":
      
    # Given String
    st = "aaaabaaxccac"
  
    # Function Call
    min_remove(st)
  
# This code is contributed by Chitranayal


C#
// C# program for the above approach
using System;
  
class GFG{
      
// Function that counts minimum 
// character that must be removed 
static void min_remove(string str) 
{ 
      
    // Length of string 
    int N = str.Length; 
  
    // Create prefix array 
    int []prefix_a = new int[N + 1]; 
    int []prefix_b = new int[N + 1]; 
    int []prefix_c = new int[N + 1]; 
  
    // Initialize first position 
    prefix_a[0] = 0; 
    prefix_b[0] = 0; 
    prefix_c[0] = 0; 
  
    // Fill prefix array 
    for(int i = 1; i <= N; i++)
    { 
        prefix_a[i] = prefix_a[i - 1] + 
                    (int)((str[i - 1] == 'a') ? 
                                   1 : 0); 
  
        prefix_b[i] = prefix_b[i - 1] +
                    (int)((str[i - 1] == 'b') ?
                                   1 : 0); 
  
        prefix_c[i] = prefix_c[i - 1] + 
                    (int)((str[i - 1] == 'c') ?
                                   1 : 0); 
    } 
  
    // Initialise maxi 
    int maxi = Int32.MinValue; 
  
    // Check all the possibilities by 
    // putting i and j at different 
    // position & find maximum among them 
    for(int i = 0; i <= N; i++)
    { 
        for(int j = i; j <= N; j++) 
        { 
            maxi = Math.Max(maxi, (prefix_a[i] +
                                  (prefix_b[j] -
                                   prefix_b[i]) +
                                  (prefix_c[N] -
                                   prefix_c[j]))); 
        } 
    } 
  
    // Print the characters to be removed 
    Console.WriteLine((N - maxi)); 
} 
  
// Driver Code 
public static void Main() 
{ 
      
    // Given String 
    string str = "aaaabaaxccac"; 
  
    // Function call 
    min_remove(str); 
} 
}
  
// This code is contributed by sanjoy_62


输出:
3

时间复杂度: O(N 2 ) ,其中N是给定字符串的长度。
空间复杂度: O(N) ,其中N是给定字符串的长度。