要替换的最小子串的长度,使每个字符的频率为 N/3
给定一个长度为N (可被 3 整除)的字符串str ,最多包含三个不同的字符,任务是找到可以替换其字符的最小子字符串的长度,以便每个字符恰好出现N/3次。
例子:
Input: str = “ABB”
Output: 1
Explanation: One optimal way is to replace the substring “B” with any character, suppose “C”.
Hence, the resulting is “ABC” having frequency of each character as N/3.
Input: str = “ABCBBB”
Output: 2
方法:给定的问题可以使用滑动窗口技术来解决。由于每个字符出现的频率应该是N/3 ,因此可以计算出字符出现的次数。这个想法是找到最小子字符串的长度,使其包含所有多余的字符,然后可以替换。以下是要遵循的步骤:
- 创建一个 map, extraChars存储str中出现超过N/3次的字符以及它们各自的多余计数。
- 使用滑动窗口查找具有给定频率的extraChar中所有字符的最短子字符串。它可以类似于在寻找包含另一个字符串的所有字符的最小子字符串的问题中讨论的那样完成。
以下是上述方法的实现:
C++
#include
using namespace std;
int balanceString(string str){
int N = str.length();
// If length of str is 0
if (N == 0) {
return 0;
}
// Stores the frequency of
// each char in str
map strFreq;
for (char c : str)
strFreq++;
// Stores the characters having
// excess occurences with count
map extraChars;
for (auto c : strFreq) {
// If there are more than N/3
// characters in the string str
if (c.second > N / 3)
extraChars = (c.second - N / 3);
}
// If no characters occurs more
// than N/3 time in the string
if (extraChars.size() == 0) {
return 0;
}
// Represents start of the window,
// end of the window and the
// required answer respectivelly
int i = 0, j = 0;
int minWindowLength = N + 1;
// Stores the number of unique
// characters to in substring
int count = extraChars.size();
while (j < N) {
// Store current character
char c = str[j];
// Check if c is an excess char
if (extraChars.find(c) != extraChars.end()) {
// Reduce Count
extraChars--;
// If window has the
// required count
if (extraChars == 0)
count--;
}
// If current window has all char
if (count == 0) {
// Reduce Window size
while (i < N && count == 0) {
// Update the minimum
// length of window
minWindowLength = min(minWindowLength, j - i + 1);
// If character at index
// i is an excess char
if (extraChars.find(str[i]) != extraChars.end()) {
// Update frequency
extraChars[str[i]]++;
// Update Count
if (extraChars[str[i]] == 1)
count++;
}
i++;
}
}
j++;
}
return minWindowLength;
}
// Driver Code
int main() {
string str = "ABCBBB";
cout << balanceString(str);
return 0;
}
// This code is contributed by hrithikgarg03188
Java
// Java code to implement above approach
import java.io.*;
import java.util.*;
class GFG {
static int balanceString(String str)
{
int N = str.length();
// If length of str is 0
if (N == 0) {
return 0;
}
// Stores the frequency of
// each char in str
HashMap strFreq
= new HashMap<>();
for (char c : str.toCharArray())
strFreq.put(c,
strFreq.getOrDefault(c, 0)
+ 1);
// Stores the characters having
// excess occurences with count
HashMap extraChars
= new HashMap<>();
for (char c : strFreq.keySet()) {
// If there are more than N/3
// characters in the string str
if (strFreq.get(c) > N / 3)
extraChars.put(c,
strFreq.get(c)
- N / 3);
}
// If no characters occurs more
// than N/3 time in the string
if (extraChars.size() == 0) {
return 0;
}
// Represents start of the window,
// end of the window and the
// required answer respectivelly
int i = 0, j = 0;
int minWindowLength = N + 1;
// Stores the number of unique
// characters to in substring
int count = extraChars.size();
while (j < N) {
// Store current character
char c = str.charAt(j);
// Check if c is an excess char
if (extraChars.containsKey(c)) {
// Reduce Count
extraChars.put(c,
extraChars.get(c)
- 1);
// If window has the
// required count
if (extraChars.get(c) == 0)
count--;
}
// If current window has all char
if (count == 0) {
// Reduce Window size
while (i < N && count == 0) {
// Update the minimum
// length of window
minWindowLength
= Math.min(minWindowLength,
j - i + 1);
// If character at index
// i is an excess char
if (extraChars.containsKey(
str.charAt(i))) {
// Update frequency
extraChars.put(
str.charAt(i),
extraChars.get(
str.charAt(i))
+ 1);
// Update Count
if (extraChars.get(
str.charAt(i))
== 1)
count++;
}
i++;
}
}
j++;
}
return minWindowLength;
}
// Driver Code
public static void main(String[] args)
{
String str = "ABCBBB";
System.out.println(balanceString(str));
}
}
Python3
# python3 code for the above approach
def balanceString(str):
N = len(str)
# If length of str is 0
if (N == 0):
return 0
# Stores the frequency of
# each char in str
strFreq = {}
for c in str:
strFreq = strFreq + 1 if c in strFreq else 1
# Stores the characters having
# excess occurences with count
extraChars = {}
for c in strFreq:
# If there are more than N/3
# characters in the string str
if (strFreq > N // 3):
extraChars = (strFreq - N // 3)
# If no characters occurs more
# than N/3 time in the string
if (len(extraChars) == 0):
return 0
# Represents start of the window,
# end of the window and the
# required answer respectivelly
i, j = 0, 0
minWindowLength = N + 1
# Stores the number of unique
# characters to in substring
count = len(extraChars)
while (j < N):
# Store current character
c = str[j]
# Check if c is an excess char
if (c in extraChars):
# Reduce Count
extraChars -= 1
# If window has the
# required count
if (extraChars == 0):
count -= 1
# If current window has all char
if (count == 0):
# Reduce Window size
while (i < N and count == 0):
# Update the minimum
# length of window
minWindowLength = min(minWindowLength, j - i + 1)
# If character at index
# i is an excess char
if (str[i] in extraChars):
# Update frequency
extraChars[str[i]] += 1
# Update Count
if (extraChars[str[i]] == 1):
count += 1
i += 1
j += 1
return minWindowLength
# Driver Code
if __name__ == "__main__":
str = "ABCBBB"
print(balanceString(str))
# This code is contributed by rakeshsahni
C#
// Java code to implement above approach
using System;
using System.Collections.Generic;
class GFG {
static int balanceString(string str)
{
int N = str.Length;
// If length of str is 0
if (N == 0) {
return 0;
}
// Stores the frequency of
// each char in str
Dictionary strFreq
= new Dictionary();
foreach(char c in str.ToCharArray())
{
if (strFreq.ContainsKey(c))
strFreq += 1;
else
strFreq = 1;
}
// Stores the characters having
// excess occurences with count
Dictionary extraChars
= new Dictionary();
foreach(KeyValuePair c in strFreq)
{
// If there are more than N/3
// characters in the string str
if (c.Value > N / 3)
extraChars = c.Value - N / 3;
}
// If no characters occurs more
// than N/3 time in the string
if (extraChars.Count == 0) {
return 0;
}
// Represents start of the window,
// end of the window and the
// required answer respectivelly
int i = 0, j = 0;
int minWindowLength = N + 1;
// Stores the number of unique
// characters to in substring
int count = extraChars.Count;
while (j < N) {
// Store current character
char c = str[j];
// Check if c is an excess char
if (extraChars.ContainsKey(c)) {
// Reduce Count
extraChars -= 1;
// If window has the
// required count
if (extraChars == 0)
count--;
}
// If current window has all char
if (count == 0) {
// Reduce Window size
while (i < N && count == 0) {
// Update the minimum
// length of window
minWindowLength = Math.Min(
minWindowLength, j - i + 1);
// If character at index
// i is an excess char
if (extraChars.ContainsKey(str[i])) {
// Update frequency
extraChars[str[i]] += 1;
// Update Count
if (extraChars[str[i]] == 1)
count++;
}
i++;
}
}
j++;
}
return minWindowLength;
}
// Driver Code
public static void Main()
{
string str = "ABCBBB";
Console.WriteLine(balanceString(str));
}
}
// This code is contributed by ukasp.
Javascript
输出
2
时间复杂度: O(N)
辅助空间: O(1)