给定一个小写字母的字符串str ,任务是从给定的字符串删除最少的字符,以便字符串可以分成 3 个子字符串str1 、 str2和str3 ,这样每个子字符串可以为空或只能包含字符‘a’ , ‘b’和‘c’分别。
例子:
Input: str = “aaaabaaxccac”
Output: 3
Explanation:
String after removing b, x, and a then, string str become “aaaaaaccc”
Now str1 = “aaaaaa”, str2 = “”, str3 = “ccc”.
The minimum character removed is 3.
Input: str = “baabcbbdcca”
Output: 4
Explanation:
String after removing b, c, d, and a then, string str become “aabbbcc”
Now str1 = “aa”, str2 = “bbb”, str3 = “cc”.
The minimum character removed is 4.
方法:这个问题可以使用贪心方法来解决。我们将使用三个前缀数组来制作字符‘a’、’b’ 和 ‘c’ 的前缀数组。每个前缀数组将分别在任何索引i处存储字母‘a’、’b’ 和 ‘c’的计数。以下是步骤:
- 创建三个前缀数组为:
- pref a [i]表示长度为 i 的前缀中字母“a”的个数。
- pref b [i]表示长度为 i 的前缀中字母“b”的个数。
- pref c [i]表示长度为 i 的前缀中字母“c”的个数。
- 为了删除最少数量的字符,结果字符串应该是最大的。
- 这个想法是固定字符串的两个位置i和j , 0 ?一世 ? j≤ N ,为了将字符串分成所有可能长度的三个部分并执行以下操作:
- 从前缀中删除除‘a’之外的所有字符,以 i 结尾,这将是字符串str1 。
- 从以 j 开头的后缀中删除除‘c’之外的所有字符,这将是字符串str3 。
- 删除除位置 i 和 j 之间的‘b’之外的所有字符,这将是字符串str2 。
- 因此,结果字符串的总长度由下式给出:
total length of (str1 + str2 + str3) = (prefa[i]) + (prefb[j] – prefb[i]) + (prefc[n] – prefc[j])
- 从给定字符串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 是给定字符串的长度。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live