Description
- Sqrt(x) Easy
Implement int sqrt(int x).
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example
-
Example 1:
Input: 4
Output: 2 -
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842…, and since
the decimal part is truncated, 2 is returned.
题意
计算非负整数x的开平方,如果开方结果为小数则取其整数部分。
思路1 二分法
这种题不知道为啥直接用math.sqrt()函数也能AC
class Solution:
def mySqrt(self, x: int) -> int:
return int(math.sqrt(x))
分析:想一想我们初中学开方是什么做的,老师教的应该是先学的平方,然后背牢1到9的平方值,到学开方时直接反向套用的吧,那如果一个数不是所背诵的1到9的结果怎么办呢?我们是不是开始从1开始数,一直数到一个接近的数附近,比如求8的开方,这不在我们的背诵结果之内呀,所以11 = 1, 22 = 4,3*3 = 9,我们知道8在4与9之间,所以也知道结果在2与3之间了。
那么这题同样的道理,我们可以从某个数开始得到这个一个范围值。那这某个数怎么确定呢,学过二分法的应该知道,二分可以快速有效地将范围缩小。
说正经的二分法吧,先取左右边界的中间值,看mid是否满足类似 22 = 4,33 = 9的条件,如果满足直接返回mid的整数部分即可。如果mid * mid > x ,说明该值偏大,应该缩小右边界,所以使right = mid;如果mid * mid < x , 说明mid还小,可以继续计算,所以使left = mid + 1。
code
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 0 :
return 0
if x == 1:
return 1
left,right = 0, x
while left < right:
mid = left + (right - left)//2
if mid * mid <= x and (mid + 1) * (mid+1) > x:
return mid
elif mid * mid > x:
right = mid
else:
left = mid + 1
思路2 牛顿迭代法
参考的这种方法,其实就是一个牛顿公式。
【笔记】牛顿迭代公式
设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f’(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f’(x0),称x1为r的一次近似值。再过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标x2 =x1-f(x1)/f’(x1),称x2为r的二次近似值。重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f’(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。
code
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 0 :
return 0
if x == 1:
return 1
res = x
while True:
temp = res
res = (res + x / res) / 2
if abs(res - temp) < 1:
break
return int(res)