我正在超过时间限制?
类似字符 问题描述 塔希尔(Tahir)和玛姆塔(Mamta)正在TCS的一个项目中工作。 Tahir作为一个问题解决者,为他的朋友Mamta提出了一个有趣的问题。
问题由长度为N的字符串组成,并且仅包含小写字母。
它将跟随Q查询,其中每个查询将包含一个整数P(1 <= P <= N),该整数表示字符串中的位置。
Mamta的任务是找到该位置存在的字母,并确定在给定位置P之前相同字母的出现次数。
Mamta忙于她的办公室工作。因此,她请您帮助她。
约束 1 <= N <= 500000
由小写字母组成的
1 <= Q <= 10000
1 <= P <= N
输入格式 第一行包含一个整数N,表示字符串的长度。
第二行包含字符串S本身仅由小写字母组成('a'-'z')。
第三行包含一个整数Q,表示将要查询的查询数。
接下来的Q行包含一个整数P(1 <= P <= N),您需要为它找到在P之前的Pth位置出现的字符的数量。
输出 对于每个查询,在单行上打印一个整数,表示答案。
测试用例
说明 示例1
输入
9
abacsddaa
2
9
3
输出
3
1
说明
这里Q = 2
对于P = 9,第9个位置的字符为“ a”。在P(即9)之前出现“ a”的次数为三。
类似地,对于P = 3,第三个字符为'a'。 P之前出现“ a”的次数(即3)是1。
import java.io.*;
public class simchar
{
public static void main(String gg[]) throws Exception
{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(reader.readLine());
String s=reader.readLine();
if(s.length()!=n) return;
int q=Integer.parseInt(reader.readLine());
int qq;
int []count=new int[q];
char someChar;
for(int j=0;j<q;j++)
{
qq=Integer.parseInt(reader.readLine());
someChar=s.charAt(qq-1);
for(int k=0;k<s.substring(0,qq-1).length();k++){
if((s.substring(0,(qq-1)).charAt(k)==someChar)) count[j]++;
}
System.out.println(count[j]);
}
reader.close();
}
}
答案 0 :(得分:1)
对于长字符串(最多500000个字母)和许多查询(最多10000个)的有效解决方案,您需要以某种方式预处理字符串数据,以便在此之后可以快速处理每个查询。我建议对于26个可能的小写字母(问题明确表示为'a'-'z')中的每个字母,找到第1个,第2个,第3个出现的位置,等等,并将其填充到数组或列表中。然后对于每个查询,在数组中进行二进制搜索以找到您作为输入的位置。然后找到的数组索引将告诉您答案。这会将您的时间复杂度从 O(s ^ 2 * q)减少到 O(s + q * log(s) )。
如果您不知道二进制搜索,请查找它。或使用Map<Integer, Integer>
代替数组或列表。
仍然更有效,构建一个与字符串长度相同的数组,并在每个索引中存储有关该索引的查询的答案。我相信可以用 O(s + q)来实现。
快乐的编码。
答案 1 :(得分:1)
除了Ole的答案,您还需要考虑一些“微”优化:
我怀疑大部分时间都将花在执行此循环上
for(int k=0;k<s.substring(0,qq-1).length();k++){
if((s.substring(0,(qq-1)).charAt(k)==someChar)) count[j]++;
}
让我们看一下两个方面:
k<s.substring(0,qq-1).length()
创建一个子字符串只是为了确定其长度。但是我们知道长度是多少:qq
!因此,您没有充分的理由就创建了一个新字符串并复制了qq
个字符。效率低下。毫无意义。
s.substring(0,(qq-1)).charAt(k)==someChar
创建另一个字符串,然后获取其第k
个字符。但是,子字符串的第k
个字符也是原始字符串k
的第s
个字符。 (考虑一下!)因此,再次创建子字符串是没有意义的。
这些不必要的计算均重复qq
次。进行了2 x qq
次相同的(不必要的)计算。
注意:此分析不考虑您的代码是正确的还是算法是最佳的。这纯粹是关于微效率。由于不必要的子字符串创建,您所做的就是将O(N^2)
算法转换为O(N^3)
算法...