第一次做刷题笔记
问题描述
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
示例 1:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
解决思路
- 对于最后输出的结果result,应该满足如下的公式
result2<x<(result+1)2 r e s u l t 2 < x < ( r e s u l t + 1 ) 2 定义两个变量“half”,“prehalf”,half表示当前状态的半值,prehalf表示前一状态的半值,当 half2>x h a l f 2 > x , 那么将 half=half/2 h a l f = h a l f / 2 ,否则 half=(half+prehalf)/2 h a l f = ( h a l f + p r e h a l f ) / 2 。
在满足上述第一点的时候,结束返回结果,否则一直执行第二点的思路。
遇见的问题
一开始没有考虑到 x=1 x = 1 的情况考虑的是特例,我直接在前面加了个判断,然后通过了 x=1 x = 1 的测试用例。但是还是存在问题。
public int mySqrt(int x) {
if(x == 1)
return 1;
int half = x/2;
int pre_half = x/2;
while(true){
if(half*half > x){
pre_half = half;
half /= 2;
}
else{
if((half+1)*(half+1) > x)
return half;
else{
half = (half + pre_half) / 2;
}
}
}
}
后来还有显示当测试用例为“2147395599”时,运行时间超时。我意识到,可能是int取值范围越界的问题,int的存储空间是4个字节,32位,那么其表示的数据的范围是:
那么当“2147395599”除以2,再求平方的时候,明显越界了,所以我将half,prehalf的变量定义为 long l o n g ,再最后 return r e t u r n 的时候再强制转换成int,考虑到题意,我这样做,不会存在数据丢失的问题,毕竟按照我上述的解题思路,必须用 long l o n g 。最后的通过代码如下,结果还不错。
答案
public int mySqrt(int x) {
if(x == 1)
return 1;
long half = x/2;
long pre_half = x/2;
while(true){
if(half*half > x){
pre_half = half;
half /= 2;
}
else{
if((half+1)*(half+1) > x)
return (int)half;
else{
half = (half + pre_half) / 2;
}
}
}
}