一.题目描述
二.题目解析
题目还是很简单的,就是对一个数进行开平方,返回的结果需要向下取整。要求是不能使用内置函数。
三.算法原理
1.暴力解法
我们只需要从1开始遍历,然后判断该值的平方等不等于目标值x。如果能直接找到一个数的平方等于目标值x,则直接返回;或者找到第一次平方大于目标值x,返回前一个值即可。
2.二分查找算法
暴力解法我们可以对其进行优化:
我们可以分析x和结果之间的关系,结果一定在1~x/2之间。然后我们仔细观察,这个区间还存在二段性:结果会将区间分为两部分,结果的左边包含结果,它的平方一定是小于等于x的;结果的右边区间平凡一定是大于x的。
根据这个二段性,我们就可以使用二分算法来解决该问题。我们仔细观察这个区间的划分,是不是有点像之前的查找区间的右端点。我们可以使用查找区间的右端点来解决。
查找区间右端点的一些细节已经在前面介绍过了: 二分查找算法——在排序数组中查找元素的第一位置和最后一个位置-优快云博客
循环条件:left<right,避免死循环
求中点:left+(right-left+1),避免死循环。
因为我们查找的区间是[1,x/2],所以对于当x<=1,需要特殊判断。
四.代码实现
// C++
class Solution
{
public:
int mySqrt(int x)
{
if (x == 1)
{
return 1;
}
if (x == 0)
{
return 0;
}
// 查找区间右端点
int left = 1;
int right = x / 2;
while (left < right)
{
long long mid = left + (right - left + 1) / 2;
if (mid * mid > x)
{
right = mid - 1;
}
else
{
left = mid;
}
}
return left;
}
};
# python
class Solution:
def mySqrt(self, x: int) -> int:
if x == 1:
return 1
if x == 0:
return 0
left,right = 1,x//2
while left < right:
mid = left + (right-left+1)//2
if mid*mid > x:
right = mid-1
else:
left = mid
return left