【问题标题】:How can I shave .1 seconds from the runtime of this program?如何从该程序的运行时间中缩短 0.1 秒?
【发布时间】:2012-05-15 06:42:03
【问题描述】:

我正在 InterviewStreet 进行练习计划,我有一个运行时间为 5.15xx 秒的解决方案,而 Java 解决方案允许的最长时间为 5 秒。我能用我在这里的东西做些什么来让它在 5 秒内完成吗?还有一个 256 MB 的限制,据我所知,这是解决问题的最节省时间和内存的解决方案......

编辑: N 和 K 的可能值是 N

我尝试了三到四种不同的算法来计算二项式系数(nCr - 或 n 选择 r,都是不同的表达方式)。一些算法涉及二维数组,如 c[n][k]。这是我提交的唯一一个没有出现某种内存错误的解决方案。答案需要输出 mod (10 ^ 6) + 3,因为 nCr * nCr 的答案非常庞大。该程序的示例运行是:

3

4 1
5 2
90 13

2
5
815483

无法在更快的机器上运行它,因为它需要在他们的机器上传递才能计数,基本上我提交代码并针对他们的测试用例运行它,我不知道他们的测试用例是什么,仅此而已输入在上面给出的范围内。

还有程序本身:

import java.math.BigInteger;
import java.util.Scanner;

public class Solution {

public BigInteger nCr(int n, int r) {
    if (r > n ) {
        return BigInteger.ZERO;
    }

    if (r > n / 2) {
        r = n - r;
    }
    BigInteger result = BigInteger.ONE;

    for (int i = 0; i < r; i++) {
        result = result.multiply(BigInteger.valueOf(n - i));
        result = result.divide(BigInteger.valueOf(i + 1));
    }
    return result;
}

public static void main(String[] args) {
    Scanner input = new Scanner( System.in );
    BigInteger m = BigInteger.valueOf(1000003);
    Solution p = new Solution();
    short T = input.nextShort(); // Number of trials
    BigInteger intermediate = BigInteger.ONE;
    int[] r = new int[T];
    int[] N = new int[T];
    int[] K = new int[T];

    short x = 0;

    while (x < T) {
    N[x] = input.nextInt();
    K[x] = input.nextInt();
    x++;
    }

    x = 0;
    while (x < T) {
    if (N[x] >= 3) { 
            r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
        } else {
            r[x] = 0;
    }
    x++;
    }

    x = 0;
    while (x < T) {
    System.out.println(r[x]);
    x++;
    }
}

}

【问题讨论】:

  • 您要解决的问题是什么?
  • 你能用 Long 代替 BigInteger 吗?
  • 在速度更快的计算机上运行它。
  • 提示,而不是解决方案:在转到 BigInteger 之前,尽可能多地使用 longs 进行数学运算。
  • 网站会在 5 秒后终止该程序,因此即使它要永远运行,它也会打印 5.1 秒左右的内容。即我怀疑你需要加快我的速度超过 0.1 秒。

标签: java optimization binomial-coefficients


【解决方案1】:

不完全确定该算法试图完成什么,但我根据您对帖子的标记猜测二项式系数。

您需要检查我的建议是否修改了结果,但看起来您可以合并两个 while 循环:

原文:

while (x < T) {
    N[x] = input.nextInt();
    K[x] = input.nextInt();
    x++;
}

x = 0;
while (x < T) {
if (N[x] >= 3) { 
        r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
    } else {
        r[x] = 0;
    }
    x++;
}

新:

x = 0;
while (x < T) {

//this has been moved from your first while loop
N[x] = input.nextInt();
K[x] = input.nextInt();

if (N[x] >= 3) { 
        r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
    } else {
        r[x] = 0;
    }
    x++;
}

【讨论】:

  • 另外,NK 数组被索引了多次。也许在每个循环中将 N[x]K[x] 值设置为局部变量并替换 r[x] = 语句中的用法可以减少几毫秒。
【解决方案2】:

尝试使用 profilerm 运行,例如 jvisualvm 并使用

运行此类

-Dcom.sun.management.jmxremote

附加到进程并启动配置文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 2021-06-19
    • 2021-01-30
    相关资源
    最近更新 更多