我正在研究HackerRank中的一个问题,但是当我运行我的代码时,我似乎错过了一个边缘情况,因为它超时了。第一个测试用例适用于我的代码!
962668800 60.5
962668801 61.5
962668802 62.5
962668803 63.5
962668804 64.5
962668805 65.5
962668806 66.5
962668807 67.5
962668808 68.5
962668809 69.5
962668810 70.5
962668860 71.5
输出:
2000-07-04T00:00:00Z 69.5
2000-07-04T00:00:00Z 70.5
我的解决方案:
public class Solution {
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
int curr_min = -1;
// how many response times per minute
int count = 0;
String curr_date = null;
// calculating 90th percentile vars
double sum = 0.0;
double sq_sum = 0.0;
while (s.hasNextLine()){
int request = s.nextInt();
double response = s.nextDouble();
// get date from seconds
String updated_date = Instant.ofEpochSecond(request).toString();
int m = Integer.parseInt(updated_date.substring(14,16)); // minute
int diff = m-curr_min;
// check to see if data only one minute apart
if (diff == 1){
// first time encountering data
if (count == 0){
if ((response >= 0) && (response <=150 )){
curr_min = m;
curr_date = updated_date;
count = 1;
sum += response;
sq_sum += response*response;
}
}else{
// calculate 90th percentile for past minute, update curr minute
double avg = sum/count;
double mean_sq = sq_sum/count;
double var = mean_sq - (avg*avg);
double std_dev = Math.sqrt(var);
double perc = avg + (1.282 * std_dev);
perc = Math.round(perc * 2) / 2.0;
System.out.println(curr_date + " " + round(perc,1));
if ((response >= 0) && (response <=150 )){
count = 1;
sum = response;
sq_sum = response * response;
curr_min = m;
curr_date = updated_date;
}
}
}else{
// within the same minute
if ((response >= 0) && (response <=150 )){
count++;
sum+= response;
sq_sum+= response * response;
}
}
}
// print out last value
double a = sum/count;
double m_sq = sq_sum/count;
double v = m_sq - (a*a);
double sd = Math.sqrt(v);
double p = a + (1.282 * sd);
p = Math.round(p * 2) / 2.0;
curr_date = curr_date.replace(curr_date.substring(17,19), "00");
System.out.println(curr_date + " " + round(p,1));
}
// round response times to 1 decimal place
private static double round (double value, int precision) {
int scale = (int) Math.pow(10, precision);
return (double) Math.round(value * scale) / scale;
}
}
当我的第一个测试用例通过时,我可能会超时的原因是什么?我动态计算所有信息,而不是使用任何数组来存储数据。
答案 0 :(得分:0)
读取输入的条件错误。仔细阅读Scanner
的文档,如果没有下一行,则hasNextLine
方法会阻止:
public boolean hasNextLine()
如果此扫描仪的输入中有另一行,则返回true。 此方法可能会在等待输入时阻止。扫描仪没有 超越任何输入。
强调我的。
所以看起来你的代码工作正常,但是当没有任何代码时它正在等待更多的输入。
此外,请不要这样做:
String updated_date = Instant.ofEpochSecond(request).toString();
int m = Integer.parseInt(updated_date.substring(14,16));
这非常糟糕,因为java有一个专用于管理时间的整个包(java.time),但是在这里你手动从String
中提取分钟字段。
这是获得分钟的更好方法:
LocalTime time = LocalTime.from(Instant.ofEpochSecond(request).atZone(ZoneId.of("UTC")));
int m = time.getMinute()