有更有效的方法吗?
给定数字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[]{});
}