如何从该程序的运行时间开始削减.1秒?

时间:2012-05-11 21:55:10

标签: java optimization binomial-coefficients

我正在使用InterviewStreet的练习程序,我有一个运行时间为5.15xx秒的解决方案,而java解决方案允许的最长时间是5秒。有什么我可以用我在这里得到的东西在5秒内得到它吗?还有256 MB的限制,因为我可以说这是解决问题的最佳时间和内存效率...

编辑: N和K的可能值是N <= 10 ^ 9且K <= N,这就是我选择使用BigInteger来做所有事情的原因。最大试验次数为10000.因此,基本上,您输入试验次数,然后输入每个试验次数的一对整数值,程序计算第二次循环中等式的二项式系数的三个版本。我认为将所有内容读入数组会更快,然后处理数组并将结果放入第三个数组以由第三个循环处理,因为我认为它可能更快。我尝试在同一个循环中执行所有操作并且运行速度较慢。

我已经尝试了三种或四种不同的算法来计算二项式系数(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++;
    }
}

}

2 个答案:

答案 0 :(得分:0)

不完全确定算法试图完成什么,但我猜测基于你的帖子标记的二项式系数。

您需要检查我的建议是否修改了结果,但看起来您可以合并两个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++;
}

答案 1 :(得分:-1)

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

运行此类

-Dcom.sun.management.jmxremote

附加到流程并启动个人资料。