leetcode力扣69. x 的平方根

题目:

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:
输入: 4
输出: 2

示例 2:
输入: 8
输出: 2

说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。

题目意思很简单,调库函数肯定不行,那么就能想到二分。

因为我们要的结果总是左边界

意思就是比如 5 的开方,2平方小,3平方大了,我们希望要的结果是 2 ,那么就是总要在左半部分更新答案,当 i > j 的时候跳出循环,就是正确答案了。

为了防止溢出,判断的时候乘法改成用除法,这样就不用 long 转型,那么改用除法就有分母为0的问题,所以我们将 x=0 和 x=1 的情况单独处理,这样左边界直接可以取到 1,右边界可以直接取到x/2.。

用到的是模板一,模板来源:
二分查找简介、二分查找的三类模板总结

class Solution {
    public int mySqrt(int x) {
        if( x<2 )return x;
        int i = 1;//去除了0和1的情况,i可以从1开始,避免x/mid出现分母为0
        int j = x/2;//去除了0和1的情况,j可以从x/2开始
        int ans = 0;
        while( i <= j ){
            int mid = i + (j-i)/2;
            if( mid <= x/mid){
                ans = mid;
                i = mid+1;
            }else{
                j = mid-1;
            }
        }
        return ans;
    }
}

虽然归类到了第一类基础模板,但是还是在二分里面做了改变,那就是 <= 的时候,都更新答案并且做了 ans 的更新。

如果严格按照基础模板,写出来应该是需要后处理的,在严格等于的情况只能处理一部分:

class Solution {
    public int mySqrt(int x) {
        if( x<2 )return x;
        int i = 1;
        int j = x/2;
        while( i <= j ){
            int mid = i + (j-i)/2;
            if( mid == x/mid && x%mid == 0 ){
                return mid;
            }
            if( mid < x/mid){
                i = mid+1;
            }else{
                j = mid-1;
            }
        }
        if( i<=x/i )return i;//需要后处理
        return i-1;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42092787/article/details/107570627