我必须找到给定数除数的偶数。为此,我尝试了。我得到了正确的输出,但是我得到的时间复杂度超过了要求。问题:-第一行包含测试用例T的数量,其后T行分别包含一个整数N输出应该是-对于每个测试用例,打印只需一行即可获得所需答案。如何降低此给定代码的复杂度?或者有人可以建议更有效的方法...

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class TestClass {
    public static void main(String args[]) throws Exception {
        // Read input from stdin and provide input before running
        String frt = "";
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        int T = Integer.parseInt(line);
        int[] inp = new int[T];
        for (int i = 0; i < T; i++) {
            int x = Integer.parseInt(br.readLine());
            inp[i] = x;

        }
        int[] ans = new int[T];
        int count = 1;
        for (int i = 0; i < T; i++) {
            int x = inp[i];
            if (x % 2 == 0) {
                for (int j = 2; j <= x / 2; j = j + 2) {
                    if (x % j == 0)
                        count++;
                }
            } else
                count = 0;
            ans[i] = count;
        }
        for (int i = 0; i < T; i++)
            System.out.println(ans[i]);
    }

}

最佳答案

 import java.io.*;

 class Ideone
 {
    public static void main (String[] args) throws Exception
    {

      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      int T = Integer.parseInt(br.readLine());
      int i,j,k,n;

      int[] inp = new int[T];
      for (i = 0; i < T; i++) {
      inp[i] = Integer.parseInt(br.readLine());
      }

     //Find all the primes numbers till the square-root of 10^9.
     int MAX, root, arrLen;
     MAX=1000000000;
     arrLen=(int)Math.sqrt(MAX);  // arrLen=31622
     boolean[] primes=new boolean[arrLen+2]; // No need to find all the primes numbers till MAX

     primes[0]=primes[1]=false;
     for(i=2;i<arrLen;i++)
           primes[i]=true;


     // Using Sieve of Eratosthenes
    // Square root of 31622 is 177.8
    root=(int)Math.sqrt(arrLen); // root=177
    for(i=2;i<=root;i++)
    {
       if(primes[i])
       {
           n=i*i;
           k=0;

           //arrLen is the length of primes array.
           for(j=n; j<arrLen; k+=1, j=n+(i*k))
                  primes[j]=false;
       }
   }

    int[] ans = new int[T];
    for( i = 0; i < T; i++) {
         n = inp[i];

         if(n%2==1)
         {
             ans[i]=0; // Odd numbers will have 0 even divisors
         }
         else
         {

          int[] facts=new int[50];
          for(k=0;k<50;k++)
              facts[k]=1;

        facts[0]=0; // fact[0] will contain the highest power of 2 that divides n.
        while(n%2==0)
        {
             facts[0]+=1;
             n=n/2;
        }

        // Prime factorizing n
        j=1;
        for( k=3; k<arrLen; k+=2)
        {
            if(primes[k] && n%k==0)
            {
                while(n%k==0)
               {
                    facts[j]+=1;
                    n=n/k;
               }
               j+=1;
            }
            if(n==1)  // To check if n has been completely divided or not.
               break;
       }

       if(n!=1) // To check if there is any prime factor greater than the square root of MAX.
       {
            facts[j]+=1;
            j+=1;
       }

       int count=1;
       for(k=0;k<j;k++)
            count=count*facts[k];

        ans[i]=count;
       }
}

   for ( i = 0; i < T; i++)
           System.out.println(ans[i]);

     }
 }


我觉得这个问题可能已经发布在任何竞争性编码平台上,可能像HackerEarth一样。如果是这样,那么请不要在StackOverFlow上发布直接问题(我认为)。
无论如何,我已经测试了我的代码,它可以正确运行。
在无法减少时间复杂度的问题中,首先请确保未创建不必要的对象。在内存中创建对象是一项耗时的操作。避免不相关地创建对象和变量。上面的代码仍然可以优化,但这会降低其可读性。 :)

同样在解决问题之前,请尝试找出各种测试用例。像奇数将有0个偶数除数。因此通过检查一个数字是否为奇数,可以减少几个运算。

上面的代码有更多解释:
一个数字的除数的数量为:(N1 + 1)(N2 + 1)(N3 + 1)...。其中N1,N2,N3等是该数字的质数的幂。
现在,如果N1是2(唯一的偶数),
那么数字的偶数除数是:N1 *(N2 + 1)*(N3 + 1)...

在事实[]数组中,事实[0]对应于N1,而N2,N3等存储在事实[1],事实[2]等中。
facts [0]初始化为0,而其他初始化为1。
该计数存储最终乘积:N1 *(N2 + 1)*(N3 + 1)...,它等于原始数的偶数除数。

09-04 12:49
查看更多