在hackerrank

时间:2018-01-04 20:12:57

标签: java performance stream request timeout

我正在研究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

enter image description here

我的解决方案:

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;
    }
}

当我的第一个测试用例通过时,我可能会超时的原因是什么?我动态计算所有信息,而不是使用任何数组来存储数据。

1 个答案:

答案 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()