zoukankan      html  css  js  c++  java
  • 快速求一个整数的平方根

    简单的迭代法:

    int sqrt(int N)
    {
        for (int i = 1; i <= N / 2; i++)
        {
            if(i * i == N ) {
                return i;
            }
            if (i * i < N && (i + 1) * (i + 1) > N) {
                return i;
            }
        }
    }
    

    折半迭代法(老师给的方法):

    int sqrt(int N)
    {
        int first = 1, last;
        while(1) {
            last = N / first;
            first = (first + last) / 2;
            if (first == last || first == last - 1) {
                return first;   
            }
        }
        return 0;
    }
    

    关于折半法的解释:

    last = N / first 可以看出 N = first * last,结合下面的 first = (first + last) / 2 可知,每一次循环都会把寻找的数的数量规模缩减为原来的一半,我们简单思考一下,先来两个实例帮助理解:

    求 20 的整数平方根:

    first last
    1 20
    10 2
    6 3
    4 5

    求 25 的整数平方根:

    first last
    1 25
    13 1
    7 3
    5 5

    我们知道,每一次迭代的时候,first和last的乘积都是N,在不能恰好开方的时候,如果last - first != 1,那么我们所求的最后的结果必定存在于first和last之间,然后我们再在下一次的迭代中将last置为N/first,first置为first和last的中间值,每一次的迭代我们都在向最终的first和last接近,使得first * first < N, last * last > N,同时last - first == 1,此时first就是我们所要求的结果。对于恰好能开方的情况,就可以同理了。

    此算法时间复杂度为 (O(log N))


    更新:

    同样是折半查找,我觉得下面的算法更容易理解一些(参考了 LeetCode 的题解):

    public int mySqrt(int x) {
        if (x == 1) {
            return 1;
        }
        int min = 0;
        int max = x;
        while (max - min > 1) {
            int m = (max + min) / 2;
            if (x / m < m) { // 这里也可以用乘法,应该要更快一点
                max = m;
            } else {
                min = m;
            }
        }
    
        return min;
    }
    

    注意,这里是 Java 代码。

  • 相关阅读:
    图片优化工具
    Mac显示和隐藏文件的命令
    C中调用LUA回调(LUA注册表)
    电信猫拨号再加路由器
    VMware NAT模式网络配置
    spring mvc 数据绑定
    银行存款余额调节表实例
    加强银行余额调节表在财务管理中的作用
    c语言typedef的用法-解惑阿!很多天书般的东西解释的不错(转)
    c语言指针详解(转载)
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/13748873.html
Copyright © 2011-2022 走看看