Leetcode 69. Sqrt(x)

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值