给定一个小写字母的字符串str和一个整数K ,任务是计算长度为K的所有子串,这些子串恰好有K个不同的字符。
例子:
Input: str = “abcc”, K = 2
Output: 2
Explanation:
Possible substrings of length K = 2 are
ab : 2 distinct characters
bc : 2 distinct characters
cc : 1 distinct character
Only two valid substrings exist {“ab”, “bc”}.
Input: str = “aabab”, K = 3
Output: 0
Explanation:
Possible substrings of length K = 3 are
aab : 2 distinct characters
aba : 2 distinct characters
bab : 2 distinct characters
No substrings of length 3 exists with exactly 3 distinct characters
天真的方法:
这个想法是生成所有长度为K的子字符串,并为每个子字符串计数不同字符的数量。如果字符串的长度为N ,则可以有N – K + 1个长度为K的子字符串。生成这些子字符串将需要O(N)复杂度,而检查每个子字符串则需要O(K)复杂度,因此将总体复杂度设为O(N * K)。
高效的方法:
这个想法是使用窗口滑动技术。维护一个大小为K的窗口,并使用HashMap保留该窗口中所有字符的计数。遍历字符串减少HashMap中前一个窗口的第一个字符的计数,并增加当前窗口的最后一个字符的频率。如果在长度为K的窗口中不同字符的计数等于K ,则将答案增加1。
下面是上述方法的实现:
C++
// C++ program to find the
// count of k length substrings
// with k distinct characters
// using sliding window
#include
using namespace std;
// Function to return the
// required count of substrings
int countSubstrings(string str, int K)
{
int N = str.size();
// Store the count
int answer = 0;
// Store the count of
// distinct characters
// in every window
unordered_map map;
// Store the frequency of
// the first K length substring
for (int i = 0; i < K; i++) {
// Increase frequency of
// i-th character
map[str[i]]++;
}
// If K distinct characters
// exist
if (map.size() == K)
answer++;
// Traverse the rest of the
// substring
for (int i = K; i < N; i++) {
// Increase the frequency
// of the last character
// of the current substring
map[str[i]]++;
// Decrease the frequency
// of the first character
// of the previous substring
map[str[i - K]]--;
// If the character is not present
// in the current substring
if (map[str[i - K]] == 0) {
map.erase(str[i - K]);
}
// If the count of distinct
// characters is 0
if (map.size() == K) {
answer++;
}
}
// Return the count
return answer;
}
// Driver code
int main()
{
// string str
string str = "aabcdabbcdc";
// integer K
int K = 3;
// Print the count of K length
// substrings with k distinct characters
cout << countSubstrings(str, K) << endl;
return 0;
}
Java
// Java program to find the count
// of k length substrings with k
// distinct characters using
// sliding window
import java.util.*;
class GFG{
// Function to return the
// required count of substrings
public static int countSubstrings(String str,
int K)
{
int N = str.length();
// Store the count
int answer = 0;
// Store the count of
// distinct characters
// in every window
Map map = new HashMap();
// Store the frequency of
// the first K length substring
for(int i = 0; i < K; i++)
{
// Increase frequency of
// i-th character
if (map.get(str.charAt(i)) == null)
{
map.put(str.charAt(i), 1);
}
else
{
map.put(str.charAt(i),
map.get(str.charAt(i)) + 1);
}
}
// If K distinct characters
// exist
if (map.size() == K)
answer++;
// Traverse the rest of the
// substring
for(int i = K; i < N; i++)
{
// Increase the frequency
// of the last character
// of the current substring
if (map.get(str.charAt(i)) == null)
{
map.put(str.charAt(i), 1);
}
else
{
map.put(str.charAt(i),
map.get(str.charAt(i)) + 1);
}
// Decrease the frequency
// of the first character
// of the previous substring
map.put(str.charAt(i - K),
map.get(str.charAt(i - K)) - 1);
// If the character is not present
// in the current substring
if (map.get(str.charAt(i - K)) == 0)
{
map.remove(str.charAt(i - K));
}
// If the count of distinct
// characters is 0
if (map.size() == K)
{
answer++;
}
}
// Return the count
return answer;
}
// Driver code
public static void main(String[] args)
{
// string str
String str = "aabcdabbcdc";
// integer K
int K = 3;
// Print the count of K length
// substrings with k distinct characters
System.out.println(countSubstrings(str, K));
}
}
// This code is contributed by grand_master
Python3
# Python3 program to find the
# count of k length substrings
# with k distinct characters
# using sliding window
# Function to return the
# required count of substrings
def countSubstrings(str, K):
N = len(str)
# Store the count
answer = 0
# Store the count of
# distinct characters
# in every window
map = {}
# Store the frequency of
# the first K length substring
for i in range(K):
# Increase frequency of
# i-th character
map[str[i]] = map.get(str[i], 0) + 1
# If K distinct characters
# exist
if (len(map) == K):
answer += 1
# Traverse the rest of the
# substring
for i in range(K, N):
# Increase the frequency
# of the last character
# of the current substring
map[str[i]] = map.get(str[i], 0) + 1
# Decrease the frequency
# of the first character
# of the previous substring
map[str[i - K]] -= 1
# If the character is not present
# in the current substring
if (map[str[i - K]] == 0):
del map[str[i - K]]
# If the count of distinct
# characters is 0
if (len(map) == K):
answer += 1
# Return the count
return answer
# Driver code
if __name__ == '__main__':
str = "aabcdabbcdc"
# Integer K
K = 3
# Print the count of K length
# substrings with k distinct characters
print(countSubstrings(str, K))
# This code is contributed by mohit kumar 29
C#
// C# program to find the count
// of k length substrings with k
// distinct characters using
// sliding window
using System;
using System.Collections.Generic;
class GFG{
// Function to return the
// required count of substrings
public static int countSubstrings(string str,
int K)
{
int N = str.Length;
// Store the count
int answer = 0;
// Store the count of
// distinct characters
// in every window
Dictionary map = new Dictionary();
// Store the frequency of
// the first K length substring
for(int i = 0; i < K; i++)
{
// Increase frequency of
// i-th character
if(!map.ContainsKey(str[i]))
{
map[str[i]] = 1;
}
else
{
map[str[i]]++;
}
}
// If K distinct characters
// exist
if (map.Count == K)
answer++;
// Traverse the rest of the
// substring
for(int i = K; i < N; i++)
{
// Increase the frequency
// of the last character
// of the current substring
if(!map.ContainsKey(str[i]))
{
map[str[i]] = 1;
}
else
{
map[str[i]]++;
}
// Decrease the frequency
// of the first character
// of the previous substring
map[str[i - K]]--;
// If the character is not present
// in the current substring
if (map[str[i - K]] == 0)
{
map.Remove(str[i - K]);
}
// If the count of distinct
// characters is 0
if (map.Count == K)
{
answer++;
}
}
// Return the count
return answer;
}
// Driver code
public static void Main(string[] args)
{
// string str
string str = "aabcdabbcdc";
// integer K
int K = 3;
// Print the count of K length
// substrings with k distinct characters
Console.Write(countSubstrings(str, K));
}
}
// This code is contributed by rutvik_56
5
时间复杂度: O(N)