题目描述:
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,由于返回类型是整数,小数部分将被舍去。
解题思路1:
当输入的x满足: x >= i*i and x < (i+1)*(i+1)
代码1:
class Solution(object):
def sqrt(self, x):
i = 0
for i in range(x+1):
if x >= i*i and x < (i+1)*(i+1):
return i
else:
i += 1
s = Solution()
x = int(input("please enter a positive integer:"))
print(s.sqrt(x))
解题思路2:
采用二分查找的方法找到平方根。
代码2:
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0 or x == 1:
return x
left = 1
right = x
mid = (1 + x) // 2
while left <= right:
if mid == x // mid: # 整除,而不是乘
return mid
elif mid > x // mid:
right = mid - 1
else:
left = mid + 1
mid = (left + right) // 2
return mid
s = Solution()
x = int(input("please enter a positive integer:"))
print(s.mySqrt(x))
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
left = 0
right = x
while (left <= right):
mid = (left + right)//2
if mid * mid == x:
return mid
elif mid * mid > x:
right = mid-1
else:
left = mid+1
return left-1
s = Solution()
x = int(input("please enter a positive integer:"))
print(s.mySqrt(x))
C++:
#include<iostream>
using namespace std;
class Solution {
public:
int mySqrt(int x) {
long int left=0; //用int的话可能会越界
long int right = x;
while(left<=right){
long int mid = (left+right)/2;
if(mid*mid==x){ //用int的话可能会越界
return mid;
}
else if (mid*mid>x){
right = mid-1;
}else{
left = mid+1;
}
}
return left-1;
}
};
int main(){
Solution s;
int x;
cout << "x = ";
cin >> x;
cout << s.mySqrt(x) << endl;
return 0;
}
解题思路3:
牛顿迭代法
这个题目的本质是让你求平方根,比如求x^2=t
,我们可以设一个函数f(x)=x^2- t
,令f(x)=0
,很明显解x就是t的平方根,在图里表示为与X
轴的交点横坐标。而我们要做的就是求出这个交点,手段是取图像上一个初始点(t,f(t))
,作它的切线,切线与X
轴交点横坐标为X0
,接下来我们又作(X0,f(X0))
的切线,有没有发现,我们作的切线再逐渐向左偏,切线与X轴的交点也慢慢接近图像与X
轴的交点,一直重复以上作切线过程,最后它们会无限逼近,到最后f(Xn)
近似等于0(i从0到n),那么我们就可以认为Xn
就是要求的平方根。
平方根的具体过程如下:
1、题目要求的是x的平方根,所以t =x,同时我们假设x0开始等于x;
2、如上图所示,过点(x0,f(x0))
做曲线的切线 ,切线方程是y1-f( x0 )=f(x0)' ( x1 - x0 )
,令y1=0
,解得x1=x0 / 2+t / (2*x0)
3、接下来重复2,即过点(x1,f(x1))
做曲线的切线,切线方程是y2-f(x1)=f(x1)'(x2-x1)
,令y2=0
,解得x2=x1 / 2 +t /(2*x1)
接着重复2,一直到 f(xn)
趋向于0,而f(xn)=xn^2-t=0
,所以最后近似解就是xn
可以看出递推方程:X[i]=X[i-1]/2 + t/(2 * X[i-1])
代码3:
class Solution:
def mySqrt(self, x: int) -> int:
# 取x0 = x
# X[i]=X[i-1]/2 + t/(2 * X[i-1])
x0 = t = x
while abs(x0*x0 - t) > 0.000001:
x0 = x0 / 2 + t / (2 * x0)
return int(x0)
s = Solution()
x = int(input("please enter a positive integer:"))
print(s.mySqrt(x))
参考链接:
[1]. leetcode 69. x 的平方根(java) (牛顿迭代法解析)
[2]. leetcode–69–x 的平方根