📌  相关文章
📜  按 Q 查询的给定范围计算子字符串中不同字符的数量

📅  最后修改于: 2021-09-03 14:48:49             🧑  作者: Mango

给定一个由大小为N的小写字母组成的字符串SQ范围内的查询[L, R] ,任务是按给定范围为每个查询打印子字符串中不同字符的计数。

例子:

朴素的方法:想法是使用散列来维护给定子字符串中每个字符的频率,然后对频率等于 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


Javascript


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 表示字母表在查询范围内的存在。
例如:

下面是上述方法的实现:

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)

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