📌  相关文章
📜  具有所有不同字符的子字符串计数

📅  最后修改于: 2021-05-04 19:59:56             🧑  作者: Mango

给定一个由小写字母组成的字符串str ,任务是查找仅由不同字符组成的可能子字符串(不一定是不同的)的数量。
例子:

天真的方法:
最简单的方法是从给定的字符串生成所有可能的子字符串,并检查每个子字符串是否包含所有不同的字符。如果字符串的长度为N ,则将有N *(N + 1)/ 2个可能的子字符串。

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

高效方法:
该问题可以通过使用两指针技术在线性时间内借助计算字符串字符的频率来解决。

此方法的详细步骤如下:

  • 考虑两个指针ij ,它们最初都指向字符串的第一个字符,即i = j = 0
  • 初始化数组Cnt [],以存储从索引ij的子字符串中的字符数(包括首尾)。
  • 现在,继续递增j指针,直到遇到一些重复的字符。在递增j的同时,将所有以j索引结尾并从ij之间的任何索引开始的子串的计数添加到答案中。所有这些子字符串将包含不同的字符,因为其中不会重复任何字符。
  • 如果在索引ij之间的子字符串中遇到某个重复的字符,要排除此重复的字符,请继续增加i指针,直到删除重复的字符为止,并相应地更新Cnt []数组。
  • 继续此过程,直到j到达字符串的末尾。字符串完全遍历后,请打印答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above appraoach
#include 
using namespace std;
 
// Function to count total
// number of valid substrings
long long int countSub(string str)
{
    int n = (int)str.size();
 
    // Stores the count of
    // substrings
    long long int ans = 0;
 
    // Stores the frequency
    // of characters
    int cnt[26];
 
    memset(cnt, 0, sizeof(cnt));
 
    // Initialised both pointers
    // to beginning of the string
    int i = 0, j = 0;
 
    while (i < n) {
 
        // If all characters in
        // substring from index i
        // to j are distinct
        if (j < n && (cnt[str[j] - 'a']
                      == 0)) {
 
            // Increment count of j-th
            // character
            cnt[str[j] - 'a']++;
 
            // Add all substring ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else {
 
            // Decrement count of j-th
            // character
            cnt[str[i] - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of substrings
    return ans;
}
 
// Driver Code
int main()
{
    string str = "gffg";
 
    cout << countSub(str);
 
    return 0;
}


Java
// Java program to implement
// the above appraoach
import java.util.*;
 
class GFG{
 
// Function to count total
// number of valid subStrings
static int countSub(String str)
{
    int n = (int)str.length();
 
    // Stores the count of
    // subStrings
    int ans = 0;
 
    // Stores the frequency
    // of characters
    int []cnt = new int[26];
 
    // Initialised both pointers
    // to beginning of the String
    int i = 0, j = 0;
 
    while (i < n)
    {
 
        // If all characters in
        // subString from index i
        // to j are distinct
        if (j < n &&
           (cnt[str.charAt(j) - 'a'] == 0))
        {
 
            // Increment count of j-th
            // character
            cnt[str.charAt(j) - 'a']++;
 
            // Add all subString ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else
        {
 
            // Decrement count of j-th
            // character
            cnt[str.charAt(i) - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of subStrings
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "gffg";
 
    System.out.print(countSub(str));
}
}
 
// This code is contributed by amal kumar choubey


Python3
# Python3 program to implement
# the above appraoach
 
# Function to count total
# number of valid substrings
def countSub(Str):
 
    n = len(Str)
 
    # Stores the count of
    # substrings
    ans = 0
 
    # Stores the frequency
    # of characters
    cnt = 26 * [0]
 
    # Initialised both pointers
    # to beginning of the string
    i, j = 0, 0
 
    while (i < n):
 
        # If all characters in
        # substring from index i
        # to j are distinct
        if (j < n and
           (cnt[ord(Str[j]) - ord('a')] == 0)):
 
            # Increment count of j-th
            # character
            cnt[ord(Str[j]) - ord('a')] += 1
 
            # Add all substring ending
            # at j and starting at any
            # index between i and j
            # to the answer
            ans += (j - i + 1)
 
            # Increment 2nd pointer
            j += 1
 
        # If some characters are repeated
        # or j pointer has reached to end
        else:
 
            # Decrement count of j-th
            # character
            cnt[ord(Str[i]) - ord('a')] -= 1
 
            # Increment first pointer
            i += 1
 
    # Return the final
    # count of substrings
    return ans
 
# Driver code
Str = "gffg"
 
print(countSub(Str))
 
# This code is contributed by divyeshrabadiya07


C#
// C# program to implement
// the above appraoach
using System;
 
class GFG{
 
// Function to count total
// number of valid subStrings
static int countSub(String str)
{
    int n = (int)str.Length;
 
    // Stores the count of
    // subStrings
    int ans = 0;
 
    // Stores the frequency
    // of characters
    int []cnt = new int[26];
 
    // Initialised both pointers
    // to beginning of the String
    int i = 0, j = 0;
 
    while (i < n)
    {
 
        // If all characters in
        // subString from index i
        // to j are distinct
        if (j < n &&
           (cnt[str[j] - 'a'] == 0))
        {
 
            // Increment count of j-th
            // character
            cnt[str[j] - 'a']++;
 
            // Add all subString ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else
        {
 
            // Decrement count of j-th
            // character
            cnt[str[i] - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of subStrings
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "gffg";
 
    Console.Write(countSub(str));
}
}
 
// This code is contributed by amal kumar choubey


输出:
6


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