2019年6月18日
目录
题目:
解决方法1:模拟二分查找法
public class mySqrt {
public static void main(String[] args){
int x = 2147395599;
int result = mySqrt(x);
System.out.println("result="+result);
}
public static int mySqrt(int x) {
if (x == 1){
return 1;
}
int result = 1;
int init = x/2;
int max = x;
while(Math.pow(init,2)> x){
max = init;
init = init /2;
}
for(int i = init;i<=max;i++){
result = i;
if(Math.pow(i,2)<=x && Math.pow(i+1,2)>x){
break;
}
}
return result;
}
}
思路:
- 计算平方值是核心,使用二分查找,确定中值和中值的平方,与输入值x比较;大于目标值则继续折半查找,小于目标值则确定了结果的范围了;时间复杂度O(log2n)【底数是2】*O(常数);
性能结果:
- 可见能优化的地方还是很多的;
- 里面的init平方会导致数字移溢出(使用了int),所以使用了Math.pow();也是很讨巧的方法;当然,强制转换数据类型也是可以的;
解决方法2:讨巧解法...
class Solution {
public int mySqrt(int x) {
return x = (int)Math.sqrt(x); //溜了,溜了
}
}
性能结果:
解决方法3:先确定左右边界,中值平方值比较
class Solution {
public int mySqrt(int x) {
long left = 0;
long right = x/2 + 1;
while (left <= right){
long mid = left + (right - left)/2;
long result = mid * mid;
if (result == (long)x){
return (int)mid;
}else if(result > x){
right = mid - 1;
}else {
left = mid + 1;
}
}
return (int)right;
}
}
思路:
- 初始值是(x/2+1)/2;中值比目标大,则右边界值减一;中值比目标小,则左边界值加一;逐渐靠拢目标值;
性能结果:
解决方法4:二分查找
public static int mySqrtV4(int x){
if (x <= 1) {
return x;
}
int l = 1;
int r = x / 2;
while (true) {
int m = l + (r - l) / 2;
if (m > x / m) {
r = m - 1;
} else if (m + 1 > x / (m + 1)) {
return m;
} else {
l = m + 1;
}
}
}
小结:
对于这道题,自己首先反应过来就是用二分查找来解决,算是有小小进步,哈哈。