给定一个由N 个字符和一个正整数K组成的字符串S ,任务是计算至少具有K 个不同字符的子字符串的数量。
例子:
Input: S = “abcca”, K = 3
Output: 4
Explanation:
The substrings that contain at least K(= 3) distinct characters are:
- “abc”: Count of distinct characters = 3.
- “abcc”: Count of distinct characters = 3.
- “abcca”: Count of distinct characters = 3.
- “bcca”: Count of distinct characters = 3.
Therefore, the total count of substrings is 4.
Input: S = “abcca”, K = 4
Output: 0
朴素方法:解决给定问题的最简单方法是生成给定字符串的所有子字符串,并计算其中至少包含K 个不同字符的子字符串。检查所有子字符串后,打印获得的总计数作为结果。
时间复杂度: O(N 3 )
辅助空间: O(256)
高效的方法:上述方法也可以通过使用滑动窗口和哈希的概念进行优化。请按照以下步骤解决问题:
- 初始化一个变量,比如ans为0以存储至少具有K 个不同字符的子字符串的计数。
- 初始化两个指针, begin和end ,存放滑动窗口的起点和终点。
- 初始化一个 HashMap,比如M来存储窗口中字符的频率。
- 迭代直到end小于N ,并执行以下步骤:
- 包括在窗口的结尾的字符,通过递增1 S [结束]在M的值。
- 迭代直到M的大小小于K ,并执行以下步骤:
- 通过递减S的值除去从窗口的起始字符由1 M [开始]。
- 如果其频率变为0 ,则将其从映射M 中删除。
- 通过将ans增加(N – end + 1) 来计算从begin到N的所有子字符串。
- 完成以上步骤后,打印ans的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count number of substrings
// having atleast k distinct characters
void atleastkDistinctChars(string s, int k)
{
// Stores the size of the string
int n = s.size();
// Initialize a HashMap
unordered_map mp;
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n) {
// Include the character at
// the end of the window
char c = s[end];
mp++;
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.size() >= k) {
// Remove the character from
// the beginning of window
char pre = s[begin];
mp[pre]--;
// If its frequency is 0,
// remove it from the map
if (mp[pre] == 0) {
mp.erase(pre);
}
// Update the answer
ans += s.length() - end + 1;
begin++;
}
}
// Print the result
cout << ans;
}
// Driver Code
int main()
{
string S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to count number of substrings
// having atleast k distinct characters
static void atleastkDistinctChars(String s, int k)
{
// Stores the size of the string
int n = s.length();
// Initialize a HashMap
Map mp = new HashMap<>();
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n) {
// Include the character at
// the end of the window
char c = s.charAt(end);
mp.put(c,mp.getOrDefault(c,0)+1);
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.size() >= k) {
// Remove the character from
// the beginning of window
char pre = s.charAt(begin);
mp.put(pre,mp.getOrDefault(pre,0)-1);
// If its frequency is 0,
// remove it from the map
if (mp.get(pre)==0){
mp.remove(pre);
}
// Update the answer
ans += s.length() - end + 1;
begin++;
}
}
// Print the result
System.out.println(ans);
}
// Driver code
public static void main (String[] args)
{
// Given inputs
String S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
}
}
// This code is contributed by offbeat
Python3
# Python 3 program for the above approach
from collections import defaultdict
# Function to count number of substrings
# having atleast k distinct characters
def atleastkDistinctChars(s, k):
# Stores the size of the string
n = len(s)
# Initialize a HashMap
mp = defaultdict(int)
# Stores the start and end
# indices of sliding window
begin = 0
end = 0
# Stores the required result
ans = 0
# Iterate while the end
# pointer is less than n
while (end < n):
# Include the character at
# the end of the window
c = s[end]
mp += 1
# Increment end pointer by 1
end += 1
# Iterate until count of distinct
# characters becomes less than K
while (len(mp) >= k):
# Remove the character from
# the beginning of window
pre = s[begin]
mp[pre] -= 1
# If its frequency is 0,
# remove it from the map
if (mp[pre] == 0):
del mp[pre]
# Update the answer
ans += len(s) - end + 1
begin += 1
# Print the result
print(ans)
# Driver Code
if __name__ == "__main__":
S = "abcca"
K = 3
atleastkDistinctChars(S, K)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to count number of substrings
// having atleast k distinct characters
static void atleastkDistinctChars(string s, int k)
{
// Stores the size of the string
int n = s.Length;
// Initialize a HashMap
Dictionary mp = new Dictionary();
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n)
{
// Include the character at
// the end of the window
char c = s[end];
if (mp.ContainsKey(c))
mp++;
else
mp.Add(c, 1);
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.Count >= k)
{
// Remove the character from
// the beginning of window
char pre = s[begin];
mp[pre]--;
// If its frequency is 0,
// remove it from the map
if (mp[pre] == 0)
{
mp.Remove(pre);
}
// Update the answer
ans += s.Length - end + 1;
begin++;
}
}
// Print the result
Console.Write(ans);
}
// Driver Code
public static void Main()
{
string S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
}
}
// This code is contributed by bgangwar59
Javascript
输出:
4
时间复杂度: O(N)
辅助空间: O(256)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。