牛顿迭代法求解平方根
假设现在输入一个整数,希望通过某种方式来求得该整数的平方根,要求得到尽可能大的精度。
和 LeetCode 上的原题 LeetCode 69 不同,这里要求得到尽可能大的精度,因此一般的二分法无法处理这个问题
处理思路
考虑定义一个函数 ,那么当 为 时,所对应的正 坐标就是 的平方根。现在,在 上的任意一点,做出 处对应的切线,此时的横坐标为 ,这条切线和 轴的交点的横坐标为 ,具体如下图所示:
由于在 处的切线的斜率为当前位置的 的倒数,因此有如下的关系:
将该关系进行转换,可以得到 和 之间的对应关系:
由于 ,由求导公式可得 ,将其带入上述的公式可得:
当 非常接近 时,则有如下的对应关系:
即经过不断地迭代,最终结果收敛于
编码实现
public static double sqrt(int n) {
int ub = 20; // 20 次左右的迭代可以解决 32 位有符号整数的平方根
double y = 0.5 * n; // 初始值默认为 0.5 倍的 n,如果能够取得更好的初始值,算法性能会有进一步的提升
double rootx = Math.sqrt(n); // 实际平方根,用于比较
for (int i = 0; i < ub; ++i) {
System.out.printf("%05d: %25.16f %25.16f\n", i, y, Math.abs(y - rootx) / rootx);
double newy = 0.5*(y + (double) n / y); // 迭代
if (newy == y) {
System.out.println("Converged");
break;
}
y = newy;
}
return y;
}
时间复杂度:可以看到,如果有一个合适的初始值,牛顿迭代法可以是一个常数时间内的操作,即
空间复杂度:只需要少量的几个中间变量,因此空间复杂度为
参考:
[1] 《编程珠矶(续)》Jon Bentley 第 14 章 编写数值计算程序
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?