对于 Q 查询,由在 [L, R] 范围内重复字符其索引时间形成的重复子串的长度
给定一个字符串S ,以及两个整数L和R 。任务是在给定范围内找到子字符串的长度,使得每个字符在其自身之后恰好重复k次,其中 k 是字母表中相应字符的索引。打印q个查询的期望结果
例子:
Input: s = “cbbde”, q = 3, queries[] = { { 2, 4 }, { 3, 5 }, { 1, 3 } };
Output: {8, 7, 11}
Explanation: Substring after recurring in the given range: “bbddddeeeee” .So, length of the substring = 11
Input: s = “xyyz”, q = 1, queries[] = {1, 2}
Output: 49
方法:该方法涉及在 O(1) 中解决每个查询的预计算思想。
- 首先,通过重复字符的索引时间来创建字符串
- 为形成的字符串中的每个字符预先计算范围 [0, i] 的重复子字符串的长度。
- 在前缀数组的帮助下,将当前字符指向的对应值的总和存储在字母表中。
- 对于每个查询,确定重复子串的长度并以 O(1) 打印结果
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of
// recurring substring in range [l, r]
int recurringSubstring(string s, int l, int r)
{
// Length of the string
int N = s.size();
// Variable to store the index of
// the character in the alphabet
int a[N];
for (int i = 0; i < N; i++) {
a[i] = (s[i] - 'a') + 1;
}
// Prefix array to store the sum
int prefix[N];
prefix[0] = a[0];
for (int i = 1; i < N; i++) {
prefix[i] = prefix[i - 1] + a[i];
}
l = l - 1;
r = r - 1;
// If l is greater than 0
if (l != 0) {
return prefix[r] - prefix[l - 1];
}
// If l is less or equal to 0
else {
return prefix[r];
}
}
void recurSubQueries(string s,
pair queries[],
int q)
{
for (int i = 0; i < q; i++) {
int l = queries[i].first;
int r = queries[i].second;
cout << recurringSubstring(s, l, r)
<< endl;
}
}
// Driver Code
int main()
{
string s = "cbbde";
int q = 3;
pair queries[]
= { { 2, 4 }, { 3, 5 }, { 1, 3 } };
recurSubQueries(s, queries, q);
return 0;
}
Java
// Java code for the above approach
import java.io.*;
class GFG
{
// Function to find the length of
// recurring substring in range [l, r]
static int recurringSubstring(String s, int l, int r)
{
// Length of the string
int N = s.length();
// Variable to store the index of
// the character in the alphabet
int a[] = new int[N];
for (int i = 0; i < N; i++) {
a[i] = (s.charAt(i) - 'a') + 1;
}
// Prefix array to store the sum
int prefix[] = new int[N];
prefix[0] = a[0];
for (int i = 1; i < N; i++) {
prefix[i] = prefix[i - 1] + a[i];
}
l = l - 1;
r = r - 1;
// If l is greater than 0
if (l != 0) {
return prefix[r] - prefix[l - 1];
}
// If l is less or equal to 0
else {
return prefix[r];
}
}
static void recurSubQueries(String s, int queries[][],
int q)
{
for (int i = 0; i < q; i++) {
int l = queries[i][0];
int r = queries[i][1];
System.out.println(recurringSubstring(s, l, r));
}
}
// Driver Code
public static void main(String[] args)
{
String s = "cbbde";
int q = 3;
int[][] queries = { { 2, 4 }, { 3, 5 }, { 1, 3 } };
recurSubQueries(s, queries, q);
}
}
// This code is contributed by Potta Lokesh
Python3
# Python code for the above approach
# Function to find the length of
# recurring substring in range [l, r]
def recurringSubstring(s, l, r):
# Length of the string
N = len(s);
# Variable to store the index of
# the character in the alphabet
a = [0 for i in range(N)];
for i in range(N):
a[i] = ord(s[i]) - ord('a') + 1;
# Prefix array to store the sum
prefix = [0 for i in range(N)];
prefix[0] = a[0];
for i in range(N):
prefix[i] = prefix[i - 1] + a[i];
l = l - 1;
r = r - 1;
# If l is greater than 0
if (l != 0):
return prefix[r] - prefix[l - 1];
# If l is less or equal to 0
else:
return prefix[r];
def recurSubQueries(s, queries, q):
for i in range(q):
l = queries[i][0];
r = queries[i][1];
print(recurringSubstring(s, l, r));
# Driver Code
if __name__ == '__main__':
s = "cbbde";
q = 3;
queries = [[2, 4], [3, 5], [1, 3]];
recurSubQueries(s, queries, q);
# This code is contributed by 29AjayKumar
C#
// C# code for the above approach
using System;
public class GFG
{
// Function to find the length of
// recurring substring in range [l, r]
static int recurringSubstring(String s, int l, int r)
{
// Length of the string
int N = s.Length;
// Variable to store the index of
// the character in the alphabet
int []a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = (s[i] - 'a') + 1;
}
// Prefix array to store the sum
int []prefix = new int[N];
prefix[0] = a[0];
for (int i = 1; i < N; i++) {
prefix[i] = prefix[i - 1] + a[i];
}
l = l - 1;
r = r - 1;
// If l is greater than 0
if (l != 0) {
return prefix[r] - prefix[l - 1];
}
// If l is less or equal to 0
else {
return prefix[r];
}
}
static void recurSubQueries(String s, int [,]queries,
int q)
{
for (int i = 0; i < q; i++) {
int l = queries[i,0];
int r = queries[i,1];
Console.WriteLine(recurringSubstring(s, l, r));
}
}
// Driver Code
public static void Main(String[] args)
{
String s = "cbbde";
int q = 3;
int[,] queries = { { 2, 4 }, { 3, 5 }, { 1, 3 } };
recurSubQueries(s, queries, q);
}
}
// This code is contributed by shikhasingrajput
Javascript
输出
8
11
7
时间复杂度:O(N+Q),其中 N 是字符串的长度
辅助空间:O(N)