给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
初看题目时,我 只觉得是一头雾水。不过这是一道二分查找的拓展题,那么首先考虑利用二分查找的方法来解决问题。
首先我们了解完条件之后,观察一下输出和输入,大致分为以下四种情况:
1.当x=0时,k(输出值)=0;
2.当x=1时,k=1;
3.当x=2时,k=1,2的算术平方根约为1.4;
4.当x=4时,k=2,算数平均根是个整数。
自然就想起了题目的另外一个要求:输出一个整数舍弃小数部分,根据以上四种结果,我们可以发现输出的值的平方小于等于x也就是输入的值。即使第一二情况特殊(输出值等于输入值),我们得到一种规律便是k*k<=x。也就是我们二分查找的边界条件,同时也进行了比较。
因此我对二分查找有了更深刻的理解,二分查找有 查找 也有 比较。
这是代码(不知道为什么一直超时,后续我会修改)
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
int middle = left + (right - left) / 2;
int result = -1;
while(left <= right){
if(middle * middle <= x){
result = middle;
left = middle + 1;
}else {
right = middle -1;
}
}
return middle;
}
};
接下来是我看了题解得出的第二个方法:牛顿迭代法。
简单介绍一下:给定一个初始值x0,函数f(x),进而得到导数f‘(x)。
f(x)过定点A(x0,f(x0))过定点A作直线y-f(x0)=f’(x0)(x-x0),令y得0得x1的值,如此这样,当xi+1-xi的绝对值小于误差时得到xi+1为f(x)零点。
本题中可以将f(x)= x*2 + x0(输入的x)
关系式为x1 = (x0 + x / x0) / 2;
class Solution {
public:
int mySqrt(int x) {
int abs(double c){ //x是所需要转化绝对值的数
if(c > 0){
return c;
}
if(c < 0){
return -c;
}
return 0;
}
if (x == 0){
return 0; //当值为0的时候
}
double x0 = x;
double x1 = (x0 + x / x0) / 2;
while(abs(x1 - x0) > 0.00001){//假设误差为0.00001
x0 = x1;
x1 = (x0 + x / x0) / 2;
}
return x1;
}
};
这就是leetcode69题,也有我的一些收获,希望你看完也能有所收获,每天更新题解。
一天一个脚印,我是老猪,明天见!