繁体   English   中英

如何使此代码更高效? Java算法

[英]How can I make this code more efficient? Java algorithm

我正在尝试以下挑战。 https://www.hackerrank.com/contests/projecteuler/challenges/euler145/submissions/code/25262675

基本上,代码需要反转大约1到19位数字的不同长度的数字,将这些数字加在一起,然后检查结果是否完全由奇数组成,不允许前导0(例如,应排除100)。

我细化的代码可以计算这些数字,但是在站点上存在超时,我认为它在性能方面还不够好。

我尝试使用正则表达式,但无法使其正确排序,并且影响了结果。 任何指导,作为最好的编写此方法的方法,以便使其尽可能快地运行,将非常有帮助,无论是否需要使用正则表达式或其他任何方法。

public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);
    long t = scan.nextInt(); //Number of numbers to test
    for (int i = 1; i <= t; i++){
        long n = scan.nextLong();
        calc(n); //begins calculation
    }
}

public static void calc(long n)
{
    long reversible = 0; //Counter
    for (long i = 1; i < n; i++)
    {
        if (i%10 != 0) //Makes sure number does not end with a zero
        {
            long reverse = 0;
            long j = i;
            long checkOdd;
            //Reverse the number
            while( j != 0 )
            {
                reverse = reverse * 10;
                reverse = reverse + j%10;
                j = j/10; //
            }
            long result = i + reverse; //Add current number and reverse
            while (result != 0)
            {
                //Check and remove numbers to see if odd or not
                checkOdd = result%10;
                if (checkOdd%2 == 0){ //Even detected, move to next number
                    result = 0;                        
                } 
                result = result/10; //Move to next digit
                //Counts and ensures we do not count the same number multiple times
                if (checkOdd%2 == 1 && result == 0) 
                {
                    reversible = reversible + 1;
                }
            }

            /** REGEX TEST CODE -- fails when result is 5 digits long after testing */
            /** if(Pattern.matches("\\d[^02468]", Long.toString(result)))
            {
                System.out.println(result);
                reversible = reversible + 1;
            }*/


        }
    }
    System.out.println(reversible);
}

这不会完全解决您的问题,但是希望可以帮助您开始思考该问题。

由于这是关于计算集合的基数的,因此我们应该考虑如何构建该集合的元素,而不是如何检查该集合中的元素。

首先,尝试考虑构造特定长度数字的方法。

我们将从一个数字开始。 我们将代表这些作为a 如果取a并将其取反,则得到a 当此值加倍时,我们得到2a ,它始终是偶数,因此总是以偶数结尾,因此没有。

接下来,输入1位数字。 ab表示,其中ab是数字。 相反的是ba ,总和的最右边位置(我将从此处开始,从0开始编号,以供将来参考)是(a+b)%10 ,因此,当和恰好是和之一时,其最后一位是奇数。 b是奇数。 另外, a+b的进位为10 ,我们称其为z 这对于下一部分很重要。 总和中的位置1(a+b+z)%10 已经确定a+b必须为奇数, z现在必须为0才能保持此奇数。 所以a+b < 10 现在,您只需要适用于的和的组合数。 请注意,两个都不能为0,因为它们位于数字的末尾。

 a | b 
 1 | 2,4,6,8
 2 | 1,3,5,7
  ... 

当然,我们真的只需要能够计算这些。 因此,对于a=1我们只需要知道b为偶数且b<9那么就有4种可能性。 对于a=2b为奇数且b<8 ,因此有4个选项。

您应该能够重现3位数字的想法,并希望通过计算可能性数量而节省的成本,而不产生或验证任何可能性,这一点将变得更加明显。

编辑:顺便说一句,没有工作去那里的三位数abc ,我得出的结论是:

a+c is odd
a+c>=10
b<=4

符合这些规则的任何组合都应该起作用。 这应该给出a,c 20组合,其中b 5独立值,因此3位数字的总和为20 * 5 = 100 希望我错了,或者您尝试时得出相同的结论。

进一步扩展时,您会注意到一些模式,可以将其推广到任意长度(我认为重要的奇数长度和偶数长度的工作方式之间可能会有一些区别)。

实际为您提供解决方案将不会有效率(并且我确信它们已经存在于某处),但是希望这可以转移您对如何解决问题的认识,从而足以解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM