给定仅具有小写字母的字符串S和Q查询,其中每个查询包含一对{L,R} 。对于每个查询{L,R},都有一个子字符串S [L,R] ,任务是找到子字符串中每个字符的频率与它们的字母顺序位置的乘积值。
注意:考虑基于1的索引。
例子:
Input: S = “abcd”, Q = { {2, 4}, {1, 3} }
Output: 9 6
Explanation:
For 1st query,
substring is S[2, 4] = “bcd”. Therefore the frequency of b, c, d are 1, 1, 1 in range 2 to 4.
value = 2*(1) + 3*(1) + 4*(1) = 9.
For 2nd query,
substring is S[1, 3] = “abc”. Therefore the frequency of a, b, c are 1, 1, 1 in range 1 to 3.
value = 1*(1) + 2*(1) + 3*(1) = 6.
Input: S = “geeksforgeeks”, Q = { {3, 3}, {2, 6}, {1, 13} }
Output: 5 46 133
幼稚的方法:幼稚的想法是遍历查询中的每个范围[L,R] ,并将每个字符的计数保留在数组中。遍历范围后,找到表达式1 *(“ a”的出现)+ 2 *(“ b”的出现)+ 3 *(“ c”的出现)+ .. + 26 *(“ z的出现”)的值’) 。
时间复杂度: O(N * Q),其中N是给定字符串的长度。
辅助空间: O(1)
高效的方法:这个想法是使用整个字符串的Prefix Sum,通过它我们可以在恒定时间内执行每个查询。步骤如下:
- 创建一个长度等于字符串长度的数组arr [] 。
- 横穿给定字符串和用于串中的每个对应的索引i,分配ARR当前字符的[I]的值– “A”。
- 找到数组arr []的前缀和。该前缀和数组将给出所有字符的出现总数,直到每个索引i为止。
- 现在,对于每个查询(例如{L,R} ), arr [R – 1] – arr [L – 2]的值将给出给定表达式的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to perform range sum queries
// on string as per the given condition
void Range_sum_query(string S,
vector > Query)
{
// Initialize N by string size
int N = S.length();
// Create array A[] for prefix sum
int A[N];
A[0] = S[0] - 'a' + 1;
// Iterate till N
for (int i = 1; i < N; i++) {
A[i] = S[i] - 'a' + 1;
A[i] = A[i] + A[i - 1];
}
// Traverse the queries
for (int i = 0; i < Query.size(); i++) {
if (Query[i].first == 1) {
// Check if if L == 1 range
// sum will be A[R-1]
cout << A[(Query[i].second) - 1]
<< endl;
}
else {
// Condition if L > 1 range sum
// will be A[R-1] - A[L-2]
cout << A[(Query[i].second) - 1]
- A[(Query[i].first) - 2]
<< endl;
}
}
}
// Driver Code
int main()
{
// Given string
string S = "abcd";
vector > Query;
// Given Queries
Query.push_back(make_pair(2, 4));
Query.push_back(make_pair(1, 3));
// Function call
Range_sum_query(S, Query);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to perform range sum queries
// on String as per the given condition
static void Range_sum_query(String S,
Vector Query)
{
// Initialize N by String size
int N = S.length();
// Create array A[] for prefix sum
int []A = new int[N];
A[0] = S.charAt(0) - 'a' + 1;
// Iterate till N
for(int i = 1; i < N; i++)
{
A[i] = S.charAt(i) - 'a' + 1;
A[i] = A[i] + A[i - 1];
}
// Traverse the queries
for(int i = 0; i < Query.size(); i++)
{
if (Query.get(i).first == 1)
{
// Check if if L == 1 range
// sum will be A[R-1]
System.out.print(
A[(Query.get(i).second) - 1] + "\n");
}
else
{
// Condition if L > 1 range sum
// will be A[R-1] - A[L-2]
System.out.print(
A[(Query.get(i).second) - 1] -
A[(Query.get(i).first) - 2] + "\n");
}
}
}
// Driver Code
public static void main(String[] args)
{
// Given String
String S = "abcd";
Vector Query = new Vector();
// Given Queries
Query.add(new pair(2, 4));
Query.add(new pair(1, 3));
// Function call
Range_sum_query(S, Query);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program for the above approach
# Function to perform range sum queries
# on string as per the given condition
def Range_sum_query(S, Query):
# Initialize N by string size
N = len(S)
# Create array A[] for prefix sum
A = [0] * N
A[0] = ord(S[0]) - ord('a') + 1
# Iterate till N
for i in range(1, N):
A[i] = ord(S[i]) - ord('a') + 1
A[i] = A[i] + A[i - 1]
# Traverse the queries
for i in range(len(Query)):
if(Query[i][0] == 1):
# Check if if L == 1 range
# sum will be A[R-1]
print(A[Query[i][1] - 1])
else:
# Condition if L > 1 range sum
# will be A[R-1] - A[L-2]
print(A[Query[i][1] - 1] -
A[Query[i][0] - 2])
# Driver Code
# Given string
S = "abcd"
Query = []
# Given Queries
Query.append([2, 4])
Query.append([1, 3])
# Function call
Range_sum_query(S, Query)
# This code is contributed by Shivam Singh
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
class pair
{
public int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to perform range sum queries
// on String as per the given condition
static void Range_sum_query(String S, List Query)
{
// Initialize N by String size
int N = S.Length;
// Create array []A for prefix sum
int[] A = new int[N];
A[0] = S[0] - 'a' + 1;
// Iterate till N
for (int i = 1; i < N; i++)
{
A[i] = S[i] - 'a' + 1;
A[i] = A[i] + A[i - 1];
}
// Traverse the queries
for (int i = 0; i < Query.Count; i++)
{
if (Query[i].first == 1)
{
// Check if if L == 1 range
// sum will be A[R-1]
Console.Write(A[(Query[i].second) - 1] + "\n");
}
else
{
// Condition if L > 1 range sum
// will be A[R-1] - A[L-2]
Console.Write(A[(Query[i].second) - 1] -
A[(Query[i].first) - 2] + "\n");
}
}
}
// Driver Code
public static void Main(String[] args)
{
// Given String
String S = "abcd";
List Query = new List();
// Given Queries
Query.Add(new pair(2, 4));
Query.Add(new pair(1, 3));
// Function call
Range_sum_query(S, Query);
}
}
// This code is contributed by gauravrajput1
9
6
时间复杂度: O(N),其中N是给定字符串的长度。
辅助空间: O(N)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。