正确的代码:
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
long long res = (right + left) / 2;
while(left <= right)
{
if(res * res == x) return res;
else if(res * res > x) right = res - 1;
else if(res * res < x) left = res + 1;
res = (right + left) / 2;
}
return res;
}
};
作者:beyonsir
链接:https://leetcode-cn.com/problems/sqrtx/solution/er-fen-cha-zhao-by-beyonsir-fnhw/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
错误的代码:
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
long long res;
while(left <= right)
{
res = (right + left) / 2;
if(res * res == x) return res;
else if(res * res > x) right = res - 1;
else if(res * res < x) left = res + 1;
}
return res;
}
};
问题:为什么只是挪动了一下res求值的位置,整个代码就不对了?看逻辑明明也是先计算后判断的呀?
细节问题。因为正确的代码在改变了left和right之后又重新计算了一次res,因为根据上一次的结果对left和right都做出了调整,所以这个res是目前最接近平方等于x的;而错误的代码用的还是上一次的res,这样一旦不满足条件退出了循环,res没有随着left和right的更新而更新,就不对了,也就是说,res没来得及用上新的left和right,更新了left和right又有什么用呢?res的值仍然是陈旧的,不正确的。
220419第二次:
Java
有个大数得转换一下才行,另外,我的意见是,保持一个模板写,别老换,换了就可能会错。
class Solution {
public int mySqrt(int x) {
int l=1,r=x;
while(l<=r)
{
int mid = l+(r-l)/2;
if((long)mid*mid<x&&(mid+1)>x/(mid+1)){
return (int)mid;
}
if((long)mid*mid>x&&(mid+1)<x/(mid+1)){
return (int)mid;
}//这两组放前面好点
if(mid<x/mid){
l=mid+1;
}
else if(mid>x/mid){
r=mid-1;
}
else return (int)mid;
}
return 0;//其实走不到这里
}
}