给定一个由小写字母组成的字符串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
Javascript
6
时间复杂度: O(N)
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live