📌  相关文章
📜  从字符串删除最小字符以在给定约束下将其拆分为三个子字符串

📅  最后修改于: 2021-10-26 06:32:34             🧑  作者: Mango

给定一个小写字母的字符串str ,任务是从给定的字符串删除最少的字符,以便字符串可以分成 3 个子字符串str1str2str3 ,这样每个子字符串可以为空或只能包含字符‘a’‘b’‘c’分别。
例子:

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

  1. 创建三个前缀数组为:
    • pref a [i]表示长度为 i 的前缀中字母“a”的个数。
    • pref b [i]表示长度为 i 的前缀中字母“b”的个数。
    • pref c [i]表示长度为 i 的前缀中字母“c”的个数。
  2. 为了删除最少数量的字符,结果字符串应该是最大的。
  3. 这个想法是固定字符串的两个位置ij0 ?一世 ? j≤ N ,为了将字符串分成所有可能长度的三个部分并执行以下操作:
    • 从前缀中删除除‘a’之外所有字符,以 i 结尾,这将是字符串str1
    • 从以 j 开头的后缀中删除除‘c’之外所有字符,这将是字符串str3
    • 删除除位置 i 和 j 之间的‘b’之外所有字符,这将是字符串str2
  4. 因此,结果字符串的总长度由下式给出:
  1. 从给定字符串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


Javascript


输出:
3

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