LeetCode - 69. Sqrt(x)

方法一:Binary Search

这道题目是一个典型的binary search问题,看似比较简单,但其实陷阱也不少。一开始直接从1到x使用binary search来寻找答案,但结果竟然TLE了,仔细想想可以发现,我们并不用从1到n寻找,只用从1到n / 2 + 1就可以了,这样就省掉了一半的时间,妈妈再也不用担心我TLE啦!可是在LeetCode上遇到x很大的test case的时候,结果仍然是错的,因为这里没有考虑到int溢出的问题,为了解决这个,我们可以使用long long,也可以使用x / mid == mid来判断,这里使用了后者,因为可以节省些空间(==.....),时间复杂度为O(logn),代码如下:

public class Solution {
    public int mySqrt(int x) {
        if(x < 0) return x;
        
        // Use binary search to find square root
        int left = 1;
        int right = x / 2 + 1;
        while(left <= right){
            int mid = (left + right) / 2;
            if(x / mid == mid) return mid;
            else if(x / mid > mid) left = mid + 1;
            else right = mid - 1;
        }
        
        return right;
    }
}

方法二:Newton's Method

public class Solution {
    public int mySqrt(int x) {
        if(x < 0) return x;
        
        double last = 0;
        double res = 1;
        while(res != last){
            last = res;
            res = (res + x / res) / 2;
        }
        return int(res);
    }
}

这里我们结束循环的判断是判断当前的x和上一个迭代中x的差是不是小于某个极小值 这里注意一个小问题,就是在java中我们可以用==来判断两个double是否相等,而在C++中我们则需要通过两个数的绝对值差小于某个极小值来判断两个double的相等性。实际上两个double因为精度问题往往是不可能每一位完全相等的,java中只是帮我们做了这种判定。所以当res == last的时候,res和last是小于某个非常小的值的,也就是达到了循环结束的条件。


知识点:

1. 当程序中出现x * x及增长速度大于x^2的计算的时候(比如x^4,指数函数)之类的情况,要尤其注意使用int会不会造成溢出的问题

2. 使用二分搜索的时候,要结合题目的情况,注意搜索的范围是不是可以优化,比如这道题目,如果搜索1到n的话,就会另外白白浪费很多的时间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值