📌  相关文章
📜  计算至少有 K 个不同字符的子串的数量

📅  最后修改于: 2021-10-28 01:43:29             🧑  作者: Mango

给定一个由N 个字符和一个正整数K组成的字符串S ,任务是计算至少具有K 个不同字符的子字符串的数量。

例子:

朴素方法:解决给定问题的最简单方法是生成给定字符串的所有子字符串,并计算其中至少包含K 个不同字符的子字符串。检查所有子字符串后,打印获得的总计数作为结果。

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

高效的方法:上述方法也可以通过使用滑动窗口和哈希的概念进行优化。请按照以下步骤解决问题:

  • 初始化一个变量,比如ans0以存储至少具有K 个不同字符的子字符串的计数。
  • 初始化两个指针, beginend ,存放滑动窗口的起点和终点。
  • 初始化一个 HashMap,比如M来存储窗口中字符的频率。
  • 迭代直到end小于N ,并执行以下步骤:
    • 包括在窗口的结尾的字符,通过递增1 S [结束]M的值。
    • 迭代直到M的大小小于K ,并执行以下步骤:
      • 通过递减S的值除去从窗口的起始字符由1 M [开始]。
      • 如果其频率变为0 ,则将其从映射M 中删除。
      • 通过将ans增加(N – end + 1) 来计算从beginN的所有子字符串。
  • 完成以上步骤后,打印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 现场工作专业课程学生竞争性编程现场课程