Solution 1: 二分搜索
自己想出来的推导关系:根号x <= 1+x/2 (x为从0到Integer.MAX_VALUE)
证明: 两边同时平方得: x <= x2+x+1
0 <=x2+1 一定成立,所以得证
- 如果正好开尽,在循环中就return了
- 如果不能正好开尽,那么我们要找最靠右的那个(类似于上天花板数)
循环退出条件是low+1==hi, 因为low找的是平方比x小的,hi永远找的是平方比x大的,low+1=hi的时候说明找到这个区间了,结果就该是low。
注意:
- 这里hi,low在移动时,不能像正常的二分法一样mid+1,mid-1,那样跨度太大,会遗漏一些
- 判断条件不能写成乘法,要写成除法,mid>x/mid,否则数一大就越界了。
class Solution {
public int mySqrt(int x) {
if(x==0)return 0;
int low=1;
//hi的初始值
int hi=x/2+1;
while(low+1<hi){
int mid=(low+hi)/2;
if(mid>x/mid){
hi=mid;
}
else if(mid<x/mid){
low=mid;
}
else{
return mid;
}
}
return low;
}
}
Solution 2: newton’ s method
https://leetcode.com/problems/sqrtx/discuss/25057/3-4-short-lines-Integer-Newton-Every-Language
wiki algorithm:
https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
long r = x;
while (r*r > x)
r = (r + x/r) / 2;
return (int) r;