题目: 给你一个非负整数 x
,计算并返回 x
的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
思路:一种常见的解决方案是使用二分查找算法。二分查找的思想是在一个有序的数据集中查找某个特定元素的算法。在这个问题中,我们可以利用二分查找来逼近计算 x 的平方根。
初始化搜索范围为 [0, x]
,分别用 l
和 r
表示左右边界。
在每一次迭代中,计算中间值 m
,然后比较 m*m
与 x
的大小:
- 如果
m*m
大于x
,则将搜索范围缩小为[l, m-1]
。- 如果
m*m
小于x
,则将搜索范围缩小为[m, r]
。- 如果
m*m
等于x
,则找到了x
的平方根,直接返回m
。
当 l
大于 r
时,结束循环,返回 r
,这是因为 r
是最接近 x
的平方根的整数部分。
代码如下:
class Solution {
public:
// 定义一个名为 mySqrt 的公有成员函数,用于计算 x 的整数部分平方根
int mySqrt(int x) {
// 如果 x 小于等于 1,则直接返回 x
if (x <= 1) {
return x;
}
// 初始化左右边界
int l = 0; // 左边界
int r = x; // 右边界
// 使用二分查找进行查找
while (l <= r) {
// 计算中间值
int m = l + (r - l) / 2;
// 将中间值的平方转换为 long long 类型,避免溢出
long long square = (long long)m * m;
// 比较中间值的平方与 x 的大小
if (square < x) { // 如果平方小于 x,则将搜索范围缩小为 [m + 1, r]
l = m + 1;
} else if (square > x) { // 如果平方大于 x,则将搜索范围缩小为 [l, m - 1]
r = m - 1;
} else if (square == x) { // 如果平方等于 x,则找到了整数部分平方根,直接返回
return m;
}
}
// 返回右边界 r,这是因为 r 是最接近 x 的整数部分平方根的整数
return r;
}
};
谢谢大家,继续努力。