题目:
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
// 二刷
class Solution {
public:
// // 法一:指数运算 + 对数运算
// int mySqrt(int x) {
// if(x == 0) return x;
// int ans = exp(0.5 * log(x)); // 注意 0.5 不是 1/2,除法向下取整
// return (long long)(ans + 1) * (ans + 1) <= x ? ans + 1 : ans;
// }
// // 法二:二分法
// int mySqrt(int x)
// {
// if(x == 0) return 0;
// int left = 1, right = x;
// // 相当于区间为 左闭右闭
// while(left <= right)
// {
// int mid =left + ((right - left) >> 1);
// if((long long)mid * mid < x)
// {
// left = mid + 1;
// }
// else if((long long)mid * mid > x) right = mid - 1;
// else return mid;
// }
// return left - 1;
// }
// 法三:二分法的第二种写法
int mySqrt(int x)
{
if(x == 0) return x;
int left = 1, right = x;
while(left <= right)
{
int mid = left + ((right - left) >> 1);
// 这种方法是与 temp 进行比较的
int temp = x / mid;
if(mid > temp) right = mid - 1;
else if(mid < temp) left = mid + 1;
else return mid;
}
return right;
}
};
class Solution {
public:
int mySqrt(int x)
{
// // 二分法,首先要有 左区间端点,右区间端点,中间点
// // 左闭右闭
// if(x == 0) return x;
// int left = 1;
// int right = x;
// int mid;
// while(left <= right)
// {
// mid = left + (right - left) / 2;
// int sq = x / mid;
// if(mid > sq)
// {
// right = mid - 1;
// }
// else if(mid < sq)
// {
// left = mid + 1;
// }
// else
// {
// return mid;
// }
// }
// return right;
// 二分法::左区间法 区间为[left, right) 左闭右开
long long left = 1, right = x;
while(left < right)
{
long long mid = left + (right - left) / 2;
//一个找左边界的问题
if(mid * mid >= x)
{
right = mid;
}
else
{
left = mid + 1;
}
}
return left * left > x ? left - 1 : left;
}
};