给定一个字符串S ,该字符串S由大小为N和Q的小写字母组成,范围为[L,R] ,则任务是为每个查询按给定范围打印子字符串中不同字符的计数。
例子:
Input: S = “geeksforgeeks”, Q[][] = {{0, 4}, {3, 7}}
Output:
4
5
Explanation:
Distinct characters in substring S[0:4] are ‘g’, ‘e’, ‘k’ and ‘s’
Distinct characters in substring in S[3:7] are ‘k’, ‘s’ ‘f’, ‘o’ and ‘r’
Input: S = “geeksforgeeksisacomputerscienceportal”, Q[][] = {{0, 10}, {15, 18}, {12, 20}}
Output:
7
4
8
天真的方法:想法是使用散列来维持给定子字符串中每个字符的频率,然后以等于1的频率对字符进行计数。
下面是上述方法的实现:
C++
// C++ Program for Naive Approach
#include
using namespace std;
void findCount(string s, int L, int R)
{
// counter to count distinct char
int distinct = 0;
// Initializing frequency array to
// count characters as the appear in
// substring S[L:R]
int frequency[26] = {};
// Iterating over S[L] to S[R]
for (int i = L; i <= R; i++) {
// incrementing the count
// of s[i] character in frequency array
frequency[s[i] - 'a']++;
}
for (int i = 0; i < 26; i++) {
// if frequency of any character is > 0
// then increment the counter
if (frequency[i] > 0)
distinct++;
}
cout << distinct << endl;
}
/* Driver code*/
int main()
{
string s = "geeksforgeeksisacomputerscienceportal";
int queries = 3;
int Q[queries][2] = { { 0, 10 },
{ 15, 18 },
{ 12, 20 } };
for (int i = 0; i < queries; i++)
findCount(s, Q[i][0], Q[i][1]);
return 0;
}
Java
// Java program for the naive approach
class GFG{
static void findCount(String s, int L,
int R)
{
// Counter to count distinct char
int distinct = 0;
// Initializing frequency array
// to count characters as the
// appear in subString S[L:R]
int []frequency = new int[26];
// Iterating over S[L] to S[R]
for(int i = L; i <= R; i++)
{
// Incrementing the count of s[i]
// character in frequency array
frequency[s.charAt(i) - 'a']++;
}
for(int i = 0; i < 26; i++)
{
// If frequency of any character
// is > 0 then increment the counter
if (frequency[i] > 0)
distinct++;
}
System.out.print(distinct + "\n");
}
// Driver code
public static void main(String[] args)
{
String s = "geeksforgeeksisa" +
"computerscienceportal";
int queries = 3;
int Q[][] = { { 0, 10 },
{ 15, 18 },
{ 12, 20 } };
for(int i = 0; i < queries; i++)
findCount(s, Q[i][0], Q[i][1]);
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for Naive Approach
def findCount(s, L, R):
# Counter to count distinct char
distinct = 0
# Initializing frequency array to
# count characters as the appear in
# substring S[L:R]
frequency = [0 for i in range(26)]
# Iterating over S[L] to S[R]
for i in range(L, R + 1, 1):
# Incrementing the count of s[i]
# character in frequency array
frequency[ord(s[i]) - ord('a')] += 1
for i in range(26):
# If frequency of any character is > 0
# then increment the counter
if (frequency[i] > 0):
distinct += 1
print(distinct)
# Driver code
if __name__ == '__main__':
s = "geeksforgeeksisacomputerscienceportal"
queries = 3
Q = [ [ 0, 10 ],
[ 15, 18 ],
[ 12, 20 ] ]
for i in range(queries):
findCount(s, Q[i][0], Q[i][1])
# This code is contributed by Bhupendra_Singh
C#
// C# program for the naive approach
using System;
class GFG{
static void findCount(String s, int L,
int R)
{
// Counter to count distinct char
int distinct = 0;
// Initializing frequency array
// to count characters as the
// appear in subString S[L:R]
int []frequency = new int[26];
// Iterating over S[L] to S[R]
for(int i = L; i <= R; i++)
{
// Incrementing the count of s[i]
// character in frequency array
frequency[s[i] - 'a']++;
}
for(int i = 0; i < 26; i++)
{
// If frequency of any character
// is > 0 then increment the counter
if (frequency[i] > 0)
distinct++;
}
Console.Write(distinct + "\n");
}
// Driver code
public static void Main(String[] args)
{
String s = "geeksforgeeksisa" +
"computerscienceportal";
int queries = 3;
int [,]Q = {{ 0, 10 },
{ 15, 18 },
{ 12, 20 }};
for(int i = 0; i < queries; i++)
findCount(s, Q[i, 0], Q[i, 1]);
}
}
// This code is contributed by sapnasingh4991
C++
// C++ Program for Efficient Approach
// to count the no. of distinct characters
// in a substring using STL
#include
using namespace std;
// vector of vector to store
// position of all characters
// as they appear in string
vector > v(26);
void build_position_vector(string s)
{
for (int i = 0; i < s.size(); i++) {
// inserting position of
// character as they appear
v[s[i] - 'a'].push_back(i);
}
}
void findCount(string s, int L, int R)
{
build_position_vector(s);
// counter to count distinct char
int distinct = 0;
// iterating over all 26 characters
for (int i = 0; i < 26; i++) {
// Finding the first element
// which is greater than or equal to L
auto first = lower_bound(
v[i].begin(),
v[i].end(), L);
// Check if first pointer exists
// and is less than or equal to R
if (first != v[i].end()
&& *first <= R) {
distinct++;
}
}
cout << distinct << endl;
}
/* Driver code*/
int main()
{
string s = "geeksforgeeksisacomputerscienceportal";
int queries = 3;
int Q[queries][2] = { { 0, 10 },
{ 15, 18 },
{ 12, 20 } };
for (int i = 0; i < queries; i++)
findCount(s, Q[i][0], Q[i][1]);
return 0;
}
输出:
7
4
8
时间复杂度: O(Q×N)
高效的方法:一种有效的方法是将每个字符的位置存储在数组中的字符串中。对于每个给定的查询,我们将迭代所有26个小写字母。如果当前字母在子字符串S [L:R]中,则对应位置矢量中第一个大于或等于L的元素应存在且小于或等于R,即,必须在L和R之间存在一个位置值R表示查询范围内是否存在字母。
例如:
下面是上述方法的实现:
C++
// C++ Program for Efficient Approach
// to count the no. of distinct characters
// in a substring using STL
#include
using namespace std;
// vector of vector to store
// position of all characters
// as they appear in string
vector > v(26);
void build_position_vector(string s)
{
for (int i = 0; i < s.size(); i++) {
// inserting position of
// character as they appear
v[s[i] - 'a'].push_back(i);
}
}
void findCount(string s, int L, int R)
{
build_position_vector(s);
// counter to count distinct char
int distinct = 0;
// iterating over all 26 characters
for (int i = 0; i < 26; i++) {
// Finding the first element
// which is greater than or equal to L
auto first = lower_bound(
v[i].begin(),
v[i].end(), L);
// Check if first pointer exists
// and is less than or equal to R
if (first != v[i].end()
&& *first <= R) {
distinct++;
}
}
cout << distinct << endl;
}
/* Driver code*/
int main()
{
string s = "geeksforgeeksisacomputerscienceportal";
int queries = 3;
int Q[queries][2] = { { 0, 10 },
{ 15, 18 },
{ 12, 20 } };
for (int i = 0; i < queries; i++)
findCount(s, Q[i][0], Q[i][1]);
return 0;
}
输出:
7
4
8
时间复杂度: O(N + Q logN)