简介
给你一个正整数 num 。如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。
不能使用任何内置的库函数,如 sqrt 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-perfect-square
思路
要判断一个正整数 num 是否是完全平方数,有多种解题思路。
二分查找法
二分查找法是一种常见的解决此类问题的方法。具体来说,我们可以在区间 [0, num] 中进行二分查找,每次取区间的中间元素 mid,比较 mid 的平方和 num 的大小,如果 mid 的平方等于 num,则返回 true,否则根据大小关系缩小区间范围继续查找。
牛顿迭代法
牛顿迭代法是一种用于求解函数零点(即函数取值为 0 的点)的方法。对于求解 f(x)=0 的问题,可以构造一个迭代公式 xn+1=xn−f′(xn)f(xn),其中 f′(xn) 表示 f(x) 在 xn 处的导数。对于判断一个数是否为完全平方数的问题,可以将其转化为求解 x2−num=0 的问题,构造迭代公式 xn+1=21(xn+xnnum)。当 xn2≈num 时,xn 即为 num 的平方根,可以将 xn 取整后和原数比较得到是否为完全平方数。
数学方法
完全平方数具有一些特殊的数学性质,可以通过这些性质来判断一个数是否为完全平方数。例如,完全平方数可以表示为连续的奇数之和,即 1+3+5+⋯,可以根据这个性质来判断一个数是否为完全平方数。
总之,判断一个数是否为完全平方数有多种方法,每种方法都有其优缺点,具体选择哪种方法需要根据具体情况来决定。
本文主要写对牛顿迭代法的思考,同时也复习一下牛顿迭代法的知识点。
对牛顿迭代法的思考
基本介绍
牛顿迭代法是一种求解非线性方程的迭代方法,其基本思想是利用泰勒展开式将非线性方程转化为一个线性方程组,然后通过不断迭代求解线性方程组来逼近方程的解。
具体来说,假设要求解非线性方程 f(x)=0,牛顿迭代法将 f(x) 在 xk 处进行一阶泰勒展开,得到:
f(x)≈f(xk)+f′(xk)(x−xk)
将上式中 f(x) 置为 0,解出 x,可以得到牛顿迭代法的迭代公式:
xk+1=xk−f′(xk)f(xk)
其中 xk 是迭代过程中第 k 次迭代得到的解,f′(xk) 是 f(x) 在 xk 处的导数。
牛顿迭代法的基本思想是利用当前解的导数信息,通过不断逼近 f(x)=0 的零点,从而求解方程的解。当 f(x) 具有一定的光滑性质时,牛顿迭代法通常可以快速收敛到方程的解。
解法
对于整个详细解法详见官方解答。这里只给出我的一些理解。
在上面给出牛顿迭代的公式:
xk+1=xk−f′(xk)f(xk)
这个公式的意义是用牛顿迭代法来求解方程 x2−num=0 的根。具体来说,迭代公式为:
xn+1=xn−2xnxn2−num
其中 xn 表示第n次迭代的结果,xn+1表示第 n+1 次迭代的结果。该迭代公式的原理是利用函数的一阶泰勒展开式来逼近方程的根。
具体来说,假设 f(x)=x2−num,则 f(x) 在点 xn 处的一阶泰勒展开式为:
f(xn+Δx)≈f(xn)+f′(xn)Δx
其中 f′(xn) 是函数 f(x) 在点 xn 处的导数,即:
f′(xn)=2xn
将 xn+1−xn 作为Δx,将上面的公式带入得到:
= x_n^2 - num + 2x_n(x_{n+1} - x_n)$$
整理得到:
$$x_{n+1} = x_n - \frac{x_n^2 - num}{2x_n} = \frac{1}{2}{(x_n+\frac{num}{x_n})} $$
每次迭代的时间复杂度为 $O(1)$,可以快速逼近方程的解。当 $x_n$ 足够接近真实解时,$x_{n+1}$ 将更加接近真实解。可以设置一个精度阈值 $\epsilon$,当 $|x_{n+1} - x_n| < \epsilon$ 时,我们认为 $x_n$ 是 $num$ 的平方根,即 $num$ 是完全平方数。对于精度阈值的设置详见官方解答。
需要注意的是,当 $num$ 很大时,使用牛顿迭代法可能会导致计算溢出或者精度问题。此时可以使用其它方法来判断 $num$ 是否是完全平方数,比如二分查找法或者数学方法。
\#\#\#\#\# 存在的问题
牛顿迭代法是求解非线性方程的一种重要方法,但它也存在以下一些缺点:
- 需要求导数:牛顿迭代法需要计算函数的一阶导数,如果导数难以求得或者计算量较大,那么牛顿迭代法的计算代价会很高。
- 可能会发散:在某些情况下,牛顿迭代法可能会发散,导致无法得到正确的解。例如,在起始点选取不当或者函数存在奇点的情况下,牛顿迭代法可能会发散。
- 对初始值敏感:牛顿迭代法的收敛性与起始点的选取有关,对于某些函数,如果起始点选取不当,可能会出现迭代结果不收敛的情况。
- {:width=200}
- 不一定收敛到全局最优解:牛顿迭代法只能收敛到局部最优解,而无法保证收敛到全局最优解。如果函数存在多个局部最优解,那么牛顿迭代法可能会收敛到其中一个局部最优解。
- {:width=200}
- 需要计算矩阵逆:在多维情况下,牛顿迭代法需要计算矩阵的逆,这样计算量比较大,并且矩阵的逆可能不存在。
图片来源于https://www.youtube.com/watch?v=OOyPMKSggAE。
\#\#\#\#\# 举个例子
下面以求解方程 $x^2 - 2 = 0$ 为例,演示如何使用牛顿迭代法。
首先,将方程写成 $f(x) = x^2 - 2$ 的形式,然后将其在某个起始点 $x_0$ 处进行一阶泰勒展开,得到:
$$f(x) \approx f(x_0) + f'(x_0)(x-x_0)$$
将上式中 $f(x)$ 置为 $0$,解出 $x$,可以得到牛顿迭代法的迭代公式:
$$x_{k+1} = x_k - \frac{f(x_k)}{f'(x_k)} = x_k - \frac{x_k^2 - 2}{2x_k} = \frac{1}{2}(x_k + \frac{2}{x_k})$$
其中 $x_k$ 是迭代过程中第 $k$ 次迭代得到的解,$f'(x_k)$ 是 $f(x)$ 在 $x_k$ 处的导数。
现在假设起始点为 $x_0 = 2$,则根据上述公式可以得到:
$$x_1 = \frac{1}{2}(x_0 + \frac{2}{x_0}) = \frac{1}{2}(2 + \frac{2}{2}) = \frac{3}{2}$$
继续迭代,可以得到:
$$x_2 = \frac{1}{2}(x_1 + \frac{2}{x_1}) = \frac{1}{2}(\frac{3}{2} + \frac{2}{\frac{3}{2}}) \approx 1.41667$$
$$x_3 = \frac{1}{2}(x_2 + \frac{2}{x_2}) \approx 1.41422$$
可以发现,经过三次迭代,可以得到方程 $x^2 - 2 = 0$ 的一个近似解 $x \approx 1.41422$,与精确解 $\sqrt{2}$ 非常接近。
> 以上仅是对牛顿迭代的一个知识点复习,用于学习和记录。与诸君共勉。