📌  相关文章
📜  要替换的最小子串的长度,使每个字符的频率为 N/3

📅  最后修改于: 2022-05-13 01:57:07.452000             🧑  作者: Mango

要替换的最小子串的长度,使每个字符的频率为 N/3

给定一个长度为N (可被 3 整除)的字符串str ,最多包含三个不同的字符,任务是找到可以替换其字符的最小子字符串的长度,以便每个字符恰好出现N/3次。

例子:

方法:给定的问题可以使用滑动窗口技术来解决。由于每个字符出现的频率应该是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)