给定一个由小写字母组成的字符串str ,任务是查找仅由不同字符组成的可能子字符串(不一定是不同的)的数量。
例子:
Input: Str = “gffg”
Output: 6
Explanation:
All possible substrings from the given string are,
( “g“, “gf“, “gff”, “gffg”, “f“, “ff”, “ffg”, “f“, “fg“, “g” )
Among them, the highlighted ones consists of distinct characters only.
Input: str = “gfg”
Output: 5
Explanation:
All possible substrings from the given string are,
( “g“, “gf“, “gfg”, “f“, “fg“, “g” )
Among them, the highlighted consists of distinct characters only.
天真的方法:
最简单的方法是从给定的字符串生成所有可能的子字符串,并检查每个子字符串是否包含所有不同的字符。如果字符串的长度为N ,则将有N *(N + 1)/ 2个可能的子字符串。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:
该问题可以通过使用两指针技术在线性时间内借助计算字符串字符的频率来解决。
此方法的详细步骤如下:
- 考虑两个指针i和j ,它们最初都指向字符串的第一个字符,即i = j = 0 。
- 初始化数组Cnt [],以存储从索引i到j的子字符串中的字符数(包括首尾)。
- 现在,继续递增j指针,直到遇到一些重复的字符。在递增j的同时,将所有以第j个索引结尾并从i和j之间的任何索引开始的子串的计数添加到答案中。所有这些子字符串将包含不同的字符,因为其中不会重复任何字符。
- 如果在索引i到j之间的子字符串中遇到某个重复的字符,要排除此重复的字符,请继续增加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)