Java阶乘超出了Kattis时间限制

时间:2018-12-07 20:47:38

标签: java algorithm

在类Main中试图查找阶乘val的最后一位,为什么

public static void main(String[] args) {
        int testcases = sc.nextInt();

        for (int i = 0; i < testcases; i++) {
            int result = 0;
            int val = sc.nextInt();
            if (val < 3) {
                result = val;
            } else {
                for (int j = 1; j <= val; j--) {
                    result *= j;
                    result %= 10;
                }
            }
            System.out.println(result);
        }

    }

除了相同的代码片段不同之外,计算所需的时间比相同的代码还要长:

 for (int j = 1; j <= val; j++) {
     result *= j;
     result %= 10;
 }

我知道第二个迭代不能提供正确的答案,但是我很好奇为什么计算第二个而不是第一个循环需要花费更长的时间。

1 个答案:

答案 0 :(得分:1)

循环代码在做什么

For循环基于3个条件多次运行代码块:

  1. 循环变量的起始值(在您的情况下为int j = 1
  2. 循环停止的条件(在您的情况下,j <= val
  3. 循环变量随每次迭代而变化的方式(在您的情况下为j--j++

j--是减量运算符。这与j = j - 1是同一件事。另一方面,j++是增量运算符。与j = j + 1

是同一回事

这意味着循环for (int j = 1; j <= val; j--)将使用j = 1运行代码块,然后减小j。只要j小于或等于val,它就会执行此操作。另一方面,循环for (int j = 1; j <= val; j++)运行代码块,然后递增 j的值,只要j较小,它将执行此操作等于或等于val

因此,对于j--,您拥有的j值的序列是1,0,-1,-2...,而对于j++所拥有的值的序列是1,2,3,4...

示例运行

让我们以val为10的示例为例。使用j++,您的循环将运行1,2,3,4,5,6,7,8,9,10,然后停止,因此它将运行10次迭代。使用j++,它将在1,0,-1,-2,-3...下运行。如您所见,这些值距离10越来越远,这是循环将停止的值。发生的是,循环一直持续运行,直到整数溢出为止。当达到int的最低值时,下一次递减迭代将导致数字的符号翻转,并且j变为最大可能的整数值,该值将大于10并中断循环。在Java中,int的标准大小为32位,因此最小的整数将为-(2^31-1),即-2,147,483,648。因此,如果您使用j--运行,则循环将在停止前运行20亿次以上,这就是为什么运行时间如此之多的原因。

相关问题