给定一个长度为N的字符串S和一个维度M×3的数组Q [] [] ,该数组由类型为{L,R,C}的查询组成,任务是在范围[L]中打印字符C的第一个索引,R] (如果找到)。否则,打印-1。
例子:
Input: S= “abcabcabc”, Q[][] = { { 0, 3, ‘a’ }, { 0, 2, ‘b’ }, { 2, 4, ‘z’ } }
Output: 0 1 -1
Explanation:
- First query: Print 0 which is the first index of character ‘a’ in the range [0, 3].
- Second query: Print 1, which is the first index of character ‘b’ in the range [0, 2].
- Third query: Print -1 as the character ‘z’ does not occur in the range [2, 4].
Input: S= “geeksforgeeks”, Q[][] = { { 0, 12, ‘f’ }, { 0, 2, ‘g’ }, { 6, 12, ‘f’ } }
Output: 5 0 -1
Explanation:
- First query: Print 5, which is the first index of character ‘f’ in the range [0, 12].
- Second query: Print 0 which is
the first index of character ‘g’ in the range [0, 2]. - Third query: Print -1 as the character ‘f’ does not occur in the range [6, 12].
天真的方法:最简单的方法是遍历每个查询的索引[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 = N或idx> 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)