给定一个字符串str和一个整数K,任务是找到最长子串的长度S,使得S中的每一个字符出现至少K倍。
例子:
Input: str = “aabbba”, K = 3
Output: 6
Explanation: In substring “aabbba”, each character repeats at least k times and its length is 6.
Input: str = “ababacb”, K = 3
Output: 0
Explanation: There is no substring where each character repeats at least k times.
朴素方法:解决给定问题的最简单方法在第 1 组中讨论。
时间复杂度: O(N 2 )
辅助空间: O(26)
分治法:针对给定问题的分治法在第 2 组中讨论。
时间复杂度: O(N*log N)
辅助空间: O(26)
高效的方法:可以通过使用滑动窗口技术进一步优化上述两种方法。请按照以下步骤解决问题:
- 将字符串str中唯一字符的数量存储在一个变量中,比如unique 。
- 使用{0}初始化大小为26的数组freq[]并将每个字符的频率存储在该数组中。
- 使用变量curr_unique迭代范围[1, unique] 。在每次迭代中, curr_unique是窗口中必须存在的唯一字符的最大数量。
- 使用{0}重新初始化数组freq[]以存储此窗口中每个字符的频率。
- 将start和end初始化为0 ,分别存储窗口的起点和终点。
- 使用两个变量CNT,用于存储唯一的字符和countK数,用于存储字符的数目与至少K的当前窗口重复字符。
- 现在,在end < N 时迭代一个循环,并执行以下操作:
- 如果cnt的值小于或等于curr_unique,则通过在窗口末尾添加一个字符从右侧扩展窗口。并将其频率在freq[] 中增加1 。
- 否则,通过从开始处删除一个字符并将其频率在freq[] 中减少1来从左侧减少窗口。
- 在每一步,更新cnt和countK的值。
- 如果cnt的值与curr_unique相同,并且每个字符至少出现K 次,则更新整体最大长度并将其存储在ans 中。
- 完成以上步骤后,打印ans的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of
// the longest substring
int longestSubstring(string s, int k)
{
// Store the required answer
int ans = 0;
// Create a frequency map of the
// characters of the string
int freq[26] = { 0 };
// Store the length of the string
int n = s.size();
// Traverse the string, s
for (int i = 0; i < n; i++)
// Increment the frequency of
// the current character by 1
freq[s[i] - 'a']++;
// Stores count of unique characters
int unique = 0;
// Find the number of unique
// characters in string
for (int i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
// Iterate in range [1, unique]
for (int curr_unique = 1;
curr_unique <= unique;
curr_unique++) {
// Initialize frequency of all
// characters as 0
memset(freq, 0, sizeof(freq));
// Stores the start and the
// end of the window
int start = 0, end = 0;
// Stores the current number of
// unique characters and characters
// occuring atleast K times
int cnt = 0, count_k = 0;
while (end < n) {
if (cnt <= curr_unique) {
int ind = s[end] - 'a';
// New unique character
if (freq[ind] == 0)
cnt++;
freq[ind]++;
// New character which
// occurs atleast k times
if (freq[ind] == k)
count_k++;
// Expand window by
// incrementing end by 1
end++;
}
else {
int ind = s[start] - 'a';
// Check if this character
// is present atleast k times
if (freq[ind] == k)
count_k--;
freq[ind]--;
// Check if this character
// is unique
if (freq[ind] == 0)
cnt--;
// Shrink the window by
// incrementing start by 1
start++;
}
// If there are curr_unique
// characters and each character
// is atleast k times
if (cnt == curr_unique
&& count_k == curr_unique)
// Update the overall
// maximum length
ans = max(ans, end - start);
}
}
// Print the answer
cout << ans;
}
// Driver Code
int main()
{
string S = "aabbba";
int K = 3;
longestSubstring(S, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to find the length of
// the longest subString
static void longestSubString(char[] s, int k)
{
// Store the required answer
int ans = 0;
// Create a frequency map of the
// characters of the String
int freq[] = new int[26];
// Store the length of the String
int n = s.length;
// Traverse the String, s
for (int i = 0; i < n; i++)
// Increment the frequency of
// the current character by 1
freq[s[i] - 'a']++;
// Stores count of unique characters
int unique = 0;
// Find the number of unique
// characters in String
for (int i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
// Iterate in range [1, unique]
for (int curr_unique = 1;
curr_unique <= unique;
curr_unique++)
{
// Initialize frequency of all
// characters as 0
Arrays.fill(freq, 0);
// Stores the start and the
// end of the window
int start = 0, end = 0;
// Stores the current number of
// unique characters and characters
// occuring atleast K times
int cnt = 0, count_k = 0;
while (end < n)
{
if (cnt <= curr_unique)
{
int ind = s[end] - 'a';
// New unique character
if (freq[ind] == 0)
cnt++;
freq[ind]++;
// New character which
// occurs atleast k times
if (freq[ind] == k)
count_k++;
// Expand window by
// incrementing end by 1
end++;
}
else
{
int ind = s[start] - 'a';
// Check if this character
// is present atleast k times
if (freq[ind] == k)
count_k--;
freq[ind]--;
// Check if this character
// is unique
if (freq[ind] == 0)
cnt--;
// Shrink the window by
// incrementing start by 1
start++;
}
// If there are curr_unique
// characters and each character
// is atleast k times
if (cnt == curr_unique
&& count_k == curr_unique)
// Update the overall
// maximum length
ans = Math.max(ans, end - start);
}
}
// Print the answer
System.out.print(ans);
}
// Driver Code
public static void main(String[] args)
{
String S = "aabbba";
int K = 3;
longestSubString(S.toCharArray(), K);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
# Function to find the length of
# the longest substring
def longestSubstring(s, k) :
# Store the required answer
ans = 0
# Create a frequency map of the
# characters of the string
freq = [0]*26
# Store the length of the string
n = len(s)
# Traverse the string, s
for i in range(n) :
# Increment the frequency of
# the current character by 1
freq[ord(s[i]) - ord('a')] += 1
# Stores count of unique characters
unique = 0
# Find the number of unique
# characters in string
for i in range(26) :
if (freq[i] != 0) :
unique += 1
# Iterate in range [1, unique]
for curr_unique in range(1, unique + 1) :
# Initialize frequency of all
# characters as 0
Freq = [0]*26
# Stores the start and the
# end of the window
start, end = 0, 0
# Stores the current number of
# unique characters and characters
# occuring atleast K times
cnt, count_k = 0, 0
while (end < n) :
if (cnt <= curr_unique) :
ind = ord(s[end]) - ord('a')
# New unique character
if (Freq[ind] == 0) :
cnt += 1
Freq[ind] += 1
# New character which
# occurs atleast k times
if (Freq[ind] == k) :
count_k += 1
# Expand window by
# incrementing end by 1
end += 1
else :
ind = ord(s[start]) - ord('a')
# Check if this character
# is present atleast k times
if (Freq[ind] == k) :
count_k -= 1
Freq[ind] -= 1
# Check if this character
# is unique
if (Freq[ind] == 0) :
cnt -= 1
# Shrink the window by
# incrementing start by 1
start += 1
# If there are curr_unique
# characters and each character
# is atleast k times
if ((cnt == curr_unique) and (count_k == curr_unique)) :
# Update the overall
# maximum length
ans = max(ans, end - start)
# Print the answer
print(ans)
S = "aabbba"
K = 3
longestSubstring(S, K)
# This code is contributed by divyesh072019.
C#
// C# program to implement
// the above approach
using System;
class GFG
{
// Function to find the length of
// the longest substring
static void longestSubstring(string s, int k)
{
// Store the required answer
int ans = 0;
// Create a frequency map of the
// characters of the string
int[] freq = new int[26];
// Store the length of the string
int n = s.Length;
// Traverse the string, s
for (int i = 0; i < n; i++)
// Increment the frequency of
// the current character by 1
freq[s[i] - 'a']++;
// Stores count of unique characters
int unique = 0;
// Find the number of unique
// characters in string
for (int i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
// Iterate in range [1, unique]
for (int curr_unique = 1;
curr_unique <= unique;
curr_unique++)
{
// Initialize frequency of all
// characters as 0
for (int i = 0; i < freq.Length; i++)
{
freq[i] = 0;
}
// Stores the start and the
// end of the window
int start = 0, end = 0;
// Stores the current number of
// unique characters and characters
// occuring atleast K times
int cnt = 0, count_k = 0;
while (end < n)
{
if (cnt <= curr_unique)
{
int ind = s[end] - 'a';
// New unique character
if (freq[ind] == 0)
cnt++;
freq[ind]++;
// New character which
// occurs atleast k times
if (freq[ind] == k)
count_k++;
// Expand window by
// incrementing end by 1
end++;
}
else
{
int ind = s[start] - 'a';
// Check if this character
// is present atleast k times
if (freq[ind] == k)
count_k--;
freq[ind]--;
// Check if this character
// is unique
if (freq[ind] == 0)
cnt--;
// Shrink the window by
// incrementing start by 1
start++;
}
// If there are curr_unique
// characters and each character
// is atleast k times
if (cnt == curr_unique
&& count_k == curr_unique)
// Update the overall
// maximum length
ans = Math.Max(ans, end - start);
}
}
// Print the answer
Console.Write(ans);
}
// Driver Code
public static void Main()
{
string S = "aabbba";
int K = 3;
longestSubstring(S, K);
}
}
// This code is contributed by splevel62.
Javascript
输出:
6
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。