总时忘记,以Leetcode69为例,来记录一下吧。
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入:x = 4
输出:2
示例 2:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 2^31 - 1
=======================================
我有两个思路,第一个是暴力解法的优化,第二个是二分法。见下面代码。这两种方法的共同点是:判断条件中得用除法if (x / i <i)而不能用乘法if (x < i * i),这是因为在x比较大的时候,i*i会出现越界,即>=2^31的情况,会报错。这个越界就是溢出。x/i是不会溢出的,所以我们要用除法进行判定,来避免溢出。
class Solution{
public:
//暴力解法,虽然进行了一定优化,但还是慢
int mySqrt(int x)
{
if (x == 0)
return 0;
if (x < 4)
return 1;
if (x < 9)
return 2;
int t = 0;
//i <= x / 3的原因:进入for循环的x是从9开始的,x/3是从3开始的,9肯定是通过if( t == i )的条件,所以输出的是i,得确保i可以取到3。
for (int i = 1; i <= x / 3; i++)
{
t = x / i;
if (t < i)
return i - 1;
if (t == i)
return i;
}
return -1;
}
//二分法
int mySqrt(int x)
{
int l = 1;
int r = x;
int mid = 0;
if (x==0)
return 0;
int t2 = 0;
while(l <= r) {
mid = l + (r - l) / 2 ; //l从1开始,所以mid不可能为0
t2 = x / mid;
if (t2 < mid) {
r = mid -1;
if (x/r >= mid)
return mid-1;
}
else if (t2 == mid)
return mid;
else
l = mid + 1;
}
return -1;
}
};