【算法-二分查找】有效的完全平方数的判断

目录

题目规则

题目分析

题目作答

使用 ​编辑 进行解题

使用 ​编辑 作答


题目规则

编写一个函数,实现完全平方数的判断,例如F(16) 是完全平方数,因为16是4的平方。

题目分析

        首先针对完全平方数进行一个回顾:完全平方指用一个整数乘以自己例如1*1,2*2,3*3等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。完全平方数是非负数,而一个完全平方数的项有两个。

        由此可知,一个数值x的完全平方数是一个正整数n的平方,同时这个n 一定是存在区间[1, x]中的一个数值,如果在这个区间中没有n,则该数值不是一个完全平方数,那么根据这个区间,我们可以构造出二分查找的左右边界,下面开始实现下。

题目作答

使用 num^2 进行解题

        上面说到,区间[1, x]中,一定有一个数值的平方是等于 x 的,因此可以将1与x作为二分边界,边界中间的基准数进行平方运算,判断是否与x相等。

  • 构建左右区间
  • 获取到区间中间数值(mid)
  • 获取到num^2 的形式(x)
  • 判断x与mid之间的关系,根据不同的关系返回不同结果
    • 如果 x == mid 满足数学逻辑,直接将true返回出去
    • 如果 x  >  mid 不满足数学逻辑,同时x较大,说明mid较大,应将右区间边界缩小
    • 如果 x  <  mid 不满足数学逻辑,同时x较小,说明mid较小,应将左区间边界缩小
    public boolean isPerfectSquare(int num) {
        if (num == 1) return true;
        int l = 0, r = num, backL = -1, backR = -1;
        while ((backL != l || backR != r) && l < r) {
            int mid = ((r - l) >> 1) + l;
            int midNumber = mid * mid;
            backL = l;
            backR = r;
            if (midNumber < 0){
                r = mid;
                continue;
            }
            if (midNumber == num) return true;
            else if (midNumber < num) l = mid;
            else r = mid;
        }
        return false;
    }

        但是这样的代码有一个小隐患,在计算机中,一个数值的存储是有上限的,如果一个数值过大,其平方数将会体现出爆炸性的增长,这种增长在计算机中会数值溢出,因此还有第二种解法,使用除法进行完全平方数值的判断。

使用 num / x 作答

        我们思考下,针对一个完全平方数值,除法中一个特点如下所示

         例如 9 是一个完全平方数,所以9 / 3 的结果还是3,这很符合我们的需求,接下来将该公式带入到二分查找的中间值中。

  • 构建左右区间
  • 获取到区间中间数值(mid)
  • 获取到num / mid 的形式(x)
  • 判断x与mid之间的关系,根据不同的关系返回不同结果
    • 如果 x == mid 满足数学逻辑,直接将true返回出去
    • 如果 x  <  mid 不满足数学逻辑,同时x较小,说明mid较大,应将右区间边界缩小
    • 如果 x  >  mid 不满足数学逻辑,同时x较大,说明mid较小,应将左区间边界缩小
    public boolean isPerfectSquare(int num) {
        if (num == 1) return true;
        int l = 0, r = num, backL = -1, backR = -1;
        while ((backL != l || backR != r) && l < r) {
            int mid = ((r - l) >> 1) + l;
            double midNumber = num / (double) mid;
            backL = l;
            backR = r;
            if (midNumber == mid) return true;
            else if (midNumber < mid) r = mid;
            else l = mid;
        }
        return false;
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值