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

📅  最后修改于: 2021-04-17 18:19:48             🧑  作者: Mango

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

例子:

天真的方法:最简单的方法是遍历每个查询的索引[L,R]范围内的字符串并在发现字符C时首次出现。否则,打印-1
时间复杂度: O(M * Q)
辅助空间: O(1)

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

  • 初始化Map >,例如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)