对于序列的每个成员,确定它是否是完美的正方形

时间:2015-04-27 02:36:42

标签: java math optimization perfect-square

我所问的不是this very popular question的副本。对于随机选择的输入,可以进行一些快速测试,如果他们不能说“不是正方形”,则必须进行平方根的一些计算(我自己也尝试了solution)。

当要测试的数字来自简单序列时,情况会有所不同,因为可以使用先前的(近似)平方根。对于一个简单的序列,它也是微不足道的,例如,

long sqrt = 1;
for (long i=1; i<limit; ++i) {
   if (sqrt*sqrt == i) {
       handleSquare(i);
       ++sqrt;
   }
}

我的问题是如何为更复杂的序列做些什么,比如

x[i] = start + i*i;

x[i] = start - i*i*i;

我正在考虑牛顿的方法,但我看不出如何快速实现(因为除法是一项非常昂贵的操作)。

1 个答案:

答案 0 :(得分:0)

您希望将哪种序列应用于算法?下面是一个解决方案,当x [i]发散但不会太快时应该可以正常工作。

例如

x[i] = a*i^p + o(i^p)

而且我足够大你会有

x[i+1]-x[i] ~ p * a * i^{p-1}.

如果y [i]表示最大的整数,那么

y[i]^2 <= x[i]

然后你有

y[i] ~ sqrt(a) i^{p/2} 

y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i]) ~ p/2 * sqrt(a) i^{p/2-1}

所以你可以把它当作y [i + 1]的猜测,然后更新到正确的值,这可以节省你一些迭代。

通常,您始终可以使用公式

y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i])

作为猜测但这仅在x [i + 1] -x [i]相对于y [i] ^ 2小时 - 即相对于x [i]时才有用。使用(精确)二阶扩展

对公式进行一点改进也是值得的
y[i+1]^2 = y[i]^2 + 2y[i](y[i+1]-y[i]) + (y[i+1]-y[i])^2

为了改善y [i + 1]的猜测。

请注意,如果当i很大或者x指数快速偏离时x [i]仍然有界,这将无法正常工作。