我正在参与在线评审页面,在那里我解决了一个问题,但我无法让我的程序及时运行。代码如下:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Set l = new HashSet();
String line;
String[] numStr;
while(true){
line = in.readLine();
numStr = line.split("\\s");
int a = Integer.parseInt(numStr[0]);
if(a == 0){
System.exit(0);
}
int n = 0;
int b = Integer.parseInt(numStr[1]);
l.clear();
for(int i=0;i<a;i++){
l.add(in.readLine());
}
for(int i=0;i<b;i++){
if(l.contains(in.readLine())){
n++;
}
}
System.out.println(n);
对于200万个项目的测试用例(numStr =“1000000 1000000”),我得到它在1.5秒以下运行,但显然这对于测试用例来说还不够(它说3000ms)。现在我不知道怎样才能让它变得更快,非常感谢任何帮助!
答案 0 :(得分:7)
输入规范的“递增顺序”部分是关键:由于两个列表都是预先排序的,您可以将第一个列表读入数组,然后使用二进制搜索从最后一个项目的位置到数组的结尾,以决定你是否匹配。实际上,即使对第一个数组进行线性搜索也可能有效,因为您最多需要遍历一次。
答案 1 :(得分:1)
假设第一个输入行是1000000 0
;你的程序会读取百万个值并将它们输入到散列中,只是没有要查找的值,因此输出保证为0.这显然需要比需要的时间长很多(你需要阅读它们,但是不要将它们存储在哈希中)。
此外,您只检查第一个值为0以终止;根据规范,0 1000000
应该产生0的输出,但是程序将终止。也许法官没有对此进行检查,但这样做是合理的。
答案 2 :(得分:1)
由于数据已排序,因此非常适合合并处理
即要处理的逻辑是
Read Jacks records into array
While (More of jacks record to process)
and (More of Jills record to process) {
if ( jacks_Record < Jills_Record)
Jacks_Array_Index += 1;
else if ( jacks_Record > Jills_Record)
Read the next Jills_Record from the file
else
Match processing
}
只有一次通过文件而没有搜索。 在某些情况下,二进制搜索可能会更快
同样值得在BufferedReader上指定一个大缓冲区