1. 题⽬链接:69.x的平⽅根
2. 题⽬描述:
3. 解法⼀(暴⼒查找):
算法思路:
依次枚举[0, x] 之间的所有数i :
(这⾥没有必要研究是否枚举到x / 2 还是x / 2 + 1 。因为我们找到结果之后直接就返回 了,往后的情况就不会再判断。反⽽研究枚举区间,既耽误时间,⼜可能出错)
▪ 如果i * i == x ,直接返回x ;
▪ 如果i * i > x ,说明之前的⼀个数是结果,返回i - 1 。 由于i * i 可能超过int 的最⼤值,因此使⽤long long 类型。
算法代码:
class Solution {
public:
int mySqrt(int x) {
// 由于两个较⼤的数相乘可能会超过 int 最⼤范围
// 因此⽤ long long
long long i = 0;
for (i = 0; i <= x; i++)
{
// 如果两个数相乘正好等于 x,直接返回 i
if (i * i == x) return i;
// 如果第⼀次出现两个数相乘⼤于 x,说明结果是前⼀个数
if (i * i > x) return i - 1;
}
// 为了处理oj题需要控制所有路径都有返回值
return -1;
}
};
4. 解法⼆(⼆分查找算法):
算法思路:
设x 的平⽅根的最终结果为index :
a. 分析index 左右两次数据的特点:
▪ [0, index] 之间的元素,平⽅之后都是⼩于等于x 的;
▪ [index + 1, x] 之间的元素,平⽅之后都是⼤于x 的。 因此可以使⽤⼆分查找算法。
C++算法代码:
class Solution
{
public:
int mySqrt(int x)
{
long long left=0,mid=0,right=x;
while(left<right)
{
mid=left+(right-left)/2+1;
if(mid*mid<=x)
{
left=mid;
}
if(mid*mid>x)
{
right=mid-1;
}
}
return right;
}
};
Java算法代码:
class Solution
{
public int mySqrt(int x)
{
// 细节
if (x < 1) return 0;
long left = 1, right = x;
while (left < right)
{
long mid = left + (right - left + 1) / 2;
if (mid * mid <= x) left = mid;
else right = mid - 1;
}
return (int)left;
}
}