有更有效的方法吗?
给定数字N-查找所有这是我的代码,但我想还有更有效的解决方案。另外,也许可以通过位操作解决它?

public static void main(String args[]) throws  Exception
 {
    long a = System.nanoTime();
    int t [] = getNumbers(4_483_647L);
    long b = System.nanoTime();
    System.out.println("Time totally "+(b-a));
    for(int k: t)
        System.out.print(k+" ");
}
public static int[] getNumbers(long N)
{

    int length=1;
    int porog=10, r=1, s=1;
    double k;
    LinkedList<Integer> list = new LinkedList<>();

    for(int i=1; i<N; i++)
    {
        if(i==porog)
        {
            length++;
            porog*=10;
        }
        s = i;
        k=0;
        while(s>0)
        {
            r = s%10;
            k+=Math.pow(r, length);
            if(k>i)break;
            s=s/10;
        }
        if((int)k==i)
            list.add(i);
    }
   int[] result  = new int[list.size()];
    int i=0;
    for(int n: list)
    {
        result[i] = n;
        i++;
    }

    return result;  }  }

最佳答案

一些观察:


如果您的初始最大值是long,则结果也应该是long类型,以防万一(int对您有用,因为自恋数字相距甚远)
如果将返回类型更改为“大” Long,则可以使用Collections.toArray()将结果重新打包到数组中...
...虽然确实是,您应该只返回链接列表...
您无需保持重新计算能力。对于外循环中的每个十年,您只需要i ^ j,其中i = 0..9,而j是当前十年中的位数
实际上,您根本不需要Math.pow(),因为您可以每十年使用一次乘法


从上面的评论中应用我的想法,并更改方法签名,您将获得大约30倍的运行速度:

public static Long[] getNumbers(long N) {
    int porog = 10;
    LinkedList<Long> list = new LinkedList<>();
    // initial powers for the number 0-9
    long[] powers = { 0l, 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l };

    for (long i = 1; i < N; i++) {
        if (i == porog) {
            porog *= 10;
            // calculate i^length
            for (int pi = 1; pi < 10; pi++) {
                powers[pi] *= pi;
            }
        }
        long s = i;
        long k = 0;
        while (s > 0) {
            int r = (int)(s % 10);
            k += powers[r];
            if (k > i)
                break;
            s /= 10;
        }

        if (k == i)
            list.add(i);
    }

    return list.toArray(new Long[]{});
}

10-08 13:02