No.69 Sqrt

深入理解并灵活运用分治思想。

1、思路一

从1到x遍历一遍,判断标准为i的平方小于等于x,而i+1的平方大于x。 

int mySqrt(int x) {
    int i=0;
    for (i=0;i<=x;i++){
        if(i*i<=x&&(i+1)*(i+1)>x)
            break;
    }
    return i;
}

结果:Wrong Answer,当input为2147395600时,output为289398,expected answer为46340。原因分析,当i=46340时,(i+1)*(i+1)发生溢出。将代码简单进行修改,方法一是将int i=0;换成long i=0;,结果为Accepted;方法二是将i*i<=x改为i<=x/i,用来确保不会发生溢出,但是第二种方法最后一个测试用例显示Time Limit Exceeded,所以需要更换算法。

2、思路二
因为求x的根号相当于1到x个数求一个数是x的根号,由于数列是有序的,适合用二分查找,时间复杂度为O(logn)。
class Solution {
public:
int mySqrt(int x) {
    if(x==0)
        return 0;
    int left = 1,right = x;
    while(1){
        int mid = left+(right-left)/2;
        if(mid>x/mid){
            right = mid-1;
        }
        else{
            if((mid+1)>x/(mid+1))
                return mid;
            left = mid+1;
        }
    }
}
};
3、思路三
class Solution {
public:
int mySqrt(int x) {
    long ans = 0;
    long bit = 1l << 16;
    while(bit > 0) {
        ans |= bit;
        if (ans * ans > x) {
            ans ^= bit;
        }
        bit >>= 1;
    }
    return (int)ans;
}
};


思路理解:int类型为16位,则从最右侧的最高有效位开始算起,如果最高有效位为1的数的平方大于x,则位数减一,当确定位数之后,再逐一确定每一位的数字的是否为1,bit是从最左一位为1,其余全是0的数,ans先将bit中的1加上,然后如果ans的平方超出x,则ans与bit做异或操作就将ans刚刚加上的1删除掉了。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值