力扣简69 x的平方根

纯暴力解

出现两个问题 1最开始设置i+1的平方大于等于x 会导致一部分测试数据出错

2最初对于测试数2147395600 一直bug 不断找问题最后才发现是后者的平方因为超int范围了

 看完题解再补充吧

 

package leetcode01;

import java.util.Scanner;

public class OthersSolution {

//最初对于测试数2147395600 一直bug 不断找问题最后才发现是后者的平方因为超int范围了

public static int mySqrt(int x) {
int res=x;
for(long i=0;i<=x;++i) {
if(((i+1)*(i+1)>x)&&(i*i<=x)){
res=(int)(i);
break;
}
}
return res;
}

public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.print(mySqrt(2147395600));

}
}

 

 

题解1

换用可使用的函数 math.exp和math.log

注意log(x)中要求x>0;而且计算中的函数运算为浮点数,会产生误差,所以最后要判定取中间数还是中间数+1.

double temp=Math.exp(0.5*Math.log(x));
return (int)(((temp+1)*(temp+1))>x?temp:temp+1);

 

题解2

困惑:为什么用L+(R-L)/2呢??解答如下:

最近在刷oj,在双指针的问题上,求中间位置索引mid总喜欢用mid = (L + R) / 2,这样好像没什么不对的,但是今天看左神的代码发现他并没有用这样的写法,而是用mid = L + ((R-L) >> 1),这是为什么呢?

其实是在实际开发中 L + R可能会造成溢出,此时再进行乘除操作都会抛异常,而使用 L + (R - L)/ 2是一种更加稳妥的方法,R - L 永远不会造成溢出,所以更加保险。而 (R - L) / 2可以写成 (R - L) >> 1,意思是右移一位。举个例子,16右移一位是多少呢?16的二进制是10000,右移一位二进制是01000,十进制等于8,相信老鸟对此并不陌生,为啥非要用右移呢?因为位运算比算术运算要快得多,所以这并不是一种装X的写法。
原文链接:https://blog.csdn.net/u011679785/article/details/114360490

题解代码如下:

public static int mySqrt(int x) {
int head=0;
int tail=x;
int ans=-1;
while(tail>=head) {
// int mid=(head+tail)/2;
// if((long)(mid*mid)>x) {
// tail=mid-1;
// }
// else if((long)(mid*mid)<x) {
// head=mid+1;
// }
// else if((long)(mid*mid)==x) {
// return mid;
// }
int mid=head+(tail-head)/2;
if((long)mid*mid<=x) {
ans=mid;
head=mid+1;
}
else {
tail=mid-1;
}
}
return ans;
}

posted @ 2022-05-13 17:24  Ssshiny  阅读(127)  评论(2)    收藏  举报