簡體   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