您的位置:首页 > 其它

Leetcode 69. Sqrt(x)

2017-01-31 04:25 435 查看
Implement int sqrt(int x).

Compute and return the square root of x.

s思路:

1.这类题用binary search. 这样复杂度就只有o(lgx)。能用binary search的原因是,sqrt(x)可以尝试从1到x,而且sqrt(x)是单调增函数,每次可以根据binary search到的candidate和结果比较来判断是所以,可以用binary search.

2. 对所有设计的运算结果习惯性的检查是否结果合法,是否超出范围。即:头脑里要有深刻意识:这是计算机处理的,而不是人类处理的,所有处理都是在一定限制下完成!

//方法1:binary search,用mid*mid<x
//一定注意:程序中所有计算都是在有限域中进行,即:计算结果都是confined with the upper and lower boundaries.
//记住:凡是运算,都需要习惯性的对计算结果是否合法进行检查
//如果不合法,要么添加保护,要么expand int to long. 
class Solution {
public:
int mySqrt(int x) {
if(x<=1) return x;
int l=1,r=x;
long lx=long(x);
while(l<r){//[l,r)左闭右开
long m=l+(r-l)/2;
if(m*m==lx) return m;//bug:在试探的时候,用m*m肯定容易越界!!
if(m*m>lx)
r=m;
else
l=m+1;
}
return l-1;
}
};


为什么返回l-1?最后跳出while时,l==r,所以返回r-1也是一样的。看最后跳出while时的代码执行情况:执行到最后一定是r-l==1,m=l,如果m*m>x,则r=m,此时:r=l,跳出while,且r*r>x,所以return r-1才行;如果m*m<x,则:l=m+1,此时:r=l=m+1,仍然跳出while,且返回m才行,而m=r-1.所以,无论如何,都是返回l-1/r-1才正确!


//方法2:除了mid*mid<x,还可以mid<x/mid,这样就不会溢出。
//同时binary search右边界可以认为是能到达的,即是在[l,r]左闭右闭。
class Solution {
public:
int mySqrt(int x) {
if(x<=1) return x;
int l=1,r=x;
while(l<=r){
long m=l+(r-l)/2;
if(m>x/m)
r=m-1;
else
l=m+1;
}
return r;
}
};


//为什么最后返回r?看程序执行情况,当l==r,m=l=r,当m*m>x,r=m-1,跳出while,此时:r*r < x,所以可以返回r;当m*m<=x,l=m+1,跳出while,此时:r*r <=x,因为m=r。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 二分搜索