📌  相关文章
📜  查询在给定范围内查找第一次出现的字符

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

给定长度为N的字符串S和维度为M × 3的数组Q[][]由类型为{L, R, C}的查询组成,任务是打印字符C在范围[L , R] ,如果找到。否则,打印-1。

例子:

朴素的方法:最简单的方法是在每个查询的索引范围[L, R]上遍历字符串,如果找到,则打印第一次出现的字符C。否则,打印-1
时间复杂度: O(M * Q)
辅助空间: O(1)

高效的方法:上述方法可以通过在向量映射中预先存储字符的索引并使用二分搜索来找到字符向量C中[L,R]范围内的索引来优化。请按照以下步骤解决问题:

  • 初始化一个 Map < char, vector < int > >,比如说V ,以存储所有出现的字符的索引。
  • 遍历字符串并更新V
  • 遍历数组Q
    • 如果V[C]的大小为零,则打印-1。
    • 否则,通过在向量V[C] 中使用二分搜索找到索引,即lower_bound(V[C].begin(), V[C].end(), L) – V[C].begin()并存储它在一个变量中,比如idx
    • 如果idx = Nidx > R ,则打印-1
    • 否则,打印索引idx

下面是上述方法的实现:

C++
// C++ implementation
// for the above approach
 
#include 
using namespace std;
 
// Function to find the first occurence
// for a given range
int firstOccurence(string s,
                   vector, char> > Q)
{
    // N = length of string
    int N = s.size();
 
    // M = length of queries
    int M = Q.size();
 
    // Stores the indices of a character
    map > v;
 
    // Traverse the string
    for (int i = 0; i < N; i++) {
 
        // Push the index i
        // into the vector[s[i]]
        v[s[i]].push_back(i);
    }
 
    // Traverse the query
    for (int i = 0; i < M; i++) {
 
        // Stores the value L
        int left = Q[i].first.first;
 
        // Stores the value R
        int right = Q[i].first.second;
 
        // Stores the character C
        char c = Q[i].second;
 
        if (v.size() == 0) {
            cout << "-1 ";
            continue;
        }
 
        // Find index >= L in
        // the vector v
        int idx
            = lower_bound(v.begin(),
                          v.end(), left)
              - v.begin();
 
        // If there is no index of C >= L
        if (idx == (int)v.size()) {
 
            cout << "-1 ";
            continue;
        }
 
        // Stores the value at idx
        idx = v[idx];
 
        // If idx > R
        if (idx > right) {
            cout << "-1 ";
        }
 
        // Otherwise
        else {
            cout << idx << " ";
        }
    }
}
 
// Driver Code
int main()
{
    string S = "abcabcabc";
    vector, char> > Q
        = { { { 0, 3 }, 'a' },
            { { 0, 2 }, 'b' },
            { { 2, 4 }, 'z' } };
 
    firstOccurence(S, Q);
    return 0;
}


Python3
# Python3 implementation
# for the above approach
from bisect import bisect_left
 
# Function to find the first occurence
# for a given range
def firstOccurence(s, Q):
   
    # N = length of string
    N = len(s)
 
    # M = length of queries
    M = len(Q)
 
    # Stores the indices of a character
    v = [[] for i in range(26)]
 
    # Traverse the string
    for i in range(N):
 
        # Push the index i
        # into the vector[s[i]]
        v[ord(s[i]) - ord('a')].append(i)
 
    # Traverse the query
    for i in range(M):
 
        # Stores the value L
        left = Q[i][0]
 
        # Stores the value R
        right = Q[i][1]
 
        # Stores the character C
        c = Q[i][2]
 
        if (len(v[ord(c) - ord('a')]) == 0):
            print ("-1")
            continue
 
        # Find index >= L in
        # the vector v
        idx = bisect_left(v[ord(c) - ord('a')], left)
 
        # If there is no index of C >= L
        if (idx == len(v[ord(c) - ord('a')])):
            print("-1 ")
            continue
 
        # Stores the value at idx
        idx = v[ord(c) - ord('a')][idx]
 
        # If idx > R
        if (idx > right):
            print ("-1 ")
             
        # Otherwise
        else:
            print(idx, end=" ")
 
# Driver Code
if __name__ == '__main__':
    S = "abcabcabc";
    Q = [ [ 0, 3 , 'a'],[ 0, 2 , 'b' ],[ 2, 4, 'z']]
 
    firstOccurence(S, Q)
 
    # This code is contributed by mohit kumar 29.


输出:
0 1 -1

时间复杂度: O(M * log(N))
辅助空间: O(N)

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