📌  相关文章
📜  具有恰好 K 个不同字符的长度为 K 的子串的计数

📅  最后修改于: 2021-10-27 08:08:00             🧑  作者: Mango

给定小写字母的字符串str和整数K ,任务是计算长度为K 且恰好具有K 个不同字符的所有子字符串。

例子:

幼稚的方法:
这个想法是生成长度为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


Javascript


输出:
5

时间复杂度: O(N)
辅助空间: O(N)