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

📅  最后修改于: 2021-09-05 11:45:49             🧑  作者: 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


Javascript


输出:
6

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live