📌  相关文章
📜  查询以查找字符串S中L到R范围内的重复字符总数

📅  最后修改于: 2021-04-22 02:52:13             🧑  作者: Mango

给定一个大小为N字符串S ,该字符串由小写字母和一个整数Q组成,整数Q表示对S的查询次数。我们的任务是为所有查询Q在子字符串L到R中打印重复字符的数量。
注意: 1≤N≤10 6和1≤Q≤10 6
例子:

天真的方法:
天真的方法是维持大小为26的频率数组,以存储每个字符的计数。对于每个查询,给定范围[L,R],我们将遍历子字符串S [L]至S [R],并继续计算每个字符的出现。现在,如果任何字符的频率大于1,那么我们将加1来回答。
高效方法:
为了有效解决上述问题,我们将每个字符在字符串中的位置存储在动态数组中。对于每个给定的查询,我们将迭代所有26个小写字母。如果当前字母在子字符串S [L:R]中,则应该存在第一个元素中对应向量中大于或等于L的下一个元素,并且小于或等于R。
下图显示了我们如何在动态数组中存储字符:

图片说明了上述方法

下面是上述方法的实现:

CPP
// CPP implementation to Find the total
// number of duplicate character in a
// range L to R for Q number of queries in a string S
 
#include 
using namespace std;
 
// Vector of vector to store
// position of all characters
// as they appear in string
vector > v(26);
 
// Function to store position of each character
void calculate(string s)
{
    for (int i = 0; i < s.size(); i++) {
        // Inserting position of each
        // character as they appear
        v[s[i] - 'a'].push_back(i);
    }
}
 
// Function to calculate duplicate
// characters for Q queries
void query(int L, int R)
{
    // Variable to count duplicates
    int duplicates = 0;
 
    // Iterate over all 26 characters
    for (int i = 0; i < 26; i++) {
 
        // Finding the first element which
        // is less than or equal to L
        auto first = lower_bound(v[i].begin(),
                                 v[i].end(), L - 1);
 
        // Check if first pointer exists
        // and is less than R
        if (first != v[i].end() && *first < R) {
            // Incrementing first pointer to check
            // if the next duplicate element exists
            first++;
 
            // Check if the next element exists
            // and is less than R
            if (first != v[i].end() && *first < R)
                duplicates++;
        }
    }
 
    cout << duplicates << endl;
}
 
// Driver Code
int main()
{
    string s = "geeksforgeeks";
 
    int Q = 2;
 
    int l1 = 1, r1 = 5;
    int l2 = 4, r2 = 8;
 
    calculate(s);
 
    query(l1, r1);
    query(l2, r2);
 
    return 0;
}


Python3
# Python implementation to Find the total
# number of duplicate character in a
# range L to R for Q number of queries in a string S
 
import bisect
 
# Vector of vector to store
# position of all characters
# as they appear in string
v = [[] for _ in range(26)]
 
# Function to store position of each character
def calculate(s: str) -> None:
 
    for i in range(len(s)):
        # Inserting position of each
        # character as they appear
        v[ord(s[i]) - ord('a')].append(i)
 
 
# Function to calculate duplicate
# characters for Q queries
def query(L: int, R: int) -> None:
 
    # Variable to count duplicates
    duplicates = 0
 
    # Iterate over all 26 characters
    for i in range(26):
 
        # Finding the first element which
        # is less than or equal to L
        first = bisect.bisect_left(v[i], L - 1)
 
        # Check if first pointer exists
        # and is less than R
        if (first < len(v[i]) and v[i][first] < R):
            # Incrementing first pointer to check
            # if the next duplicate element exists
            first += 1
 
            # Check if the next element exists
            # and is less than R
            if (first < len(v[i]) and v[i][first] < R):
                duplicates += 1
 
    print(duplicates)
 
 
# Driver Code
if __name__ == "__main__":
 
    s = "geeksforgeeks"
 
    Q = 2
 
    l1 = 1
    r1 = 5
    l2 = 4
    r2 = 8
 
    calculate(s)
 
    query(l1, r1)
    query(l2, r2)
 
# This code is contributed by sanjeev2552


输出:
1
0

`
时间复杂度: O(Q * 26 * log N)