LeetCode——x 的平方根/有效的完全平方数

摘要:
计算并返回x的平方根,其中x是非负整数。令左边界为2,右边界为x/2。借鉴@liweiwei1419的推算:代码:publicintmySqrt{longn=x;while{n=/2;}returnn;}类似解决:有效的完全平方数Q:给定一个正整数num,编写一个函数,如果num是一个完全平方数,则返回True,否则返回False。示例1:输入:16输出:True示例2:输入:14输出:FalseA:借鉴算平方根的代码。

Q:实现int sqrt(int x)函数。
计算并返回x的平方根,其中x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

A:
题目并不难,但不同的方法里面关于边界都有大大小小的坑。最好是自己写,才能知道坑在哪里……尤其注意最大值和0
1.二分法
算法:

如果 x < 2,返回 x。
令左边界为 2,右边界为 x / 2。
当 left <= right 时:
令 mid = (left + right) / 2,比较 mid * mid 与 x:
如果 mid * mid > x,更新右边界为 right = mid -1。
如果 mid * mid < x,更新左边界为 left = mid + 1。
如果 mid * mid == x,即整数平方根为 mid,返回 mid。
返回 right。

    public int mySqrt(int x) {
        if (x < 2)//特殊用例
            return x;
        long left = 2;//对待特殊用例,例如Integer.MAX_VALUE,使用long,解决求mid的问题
        long right = x / 2;
        while (left <= right) {
            long mid = (left + right) >>> 1;//无符号右移,相当于/2
            long square = mid * mid;
            if (square > x) {
                right = mid - 1;
            } else if (square < x) {
                left = mid + 1;
            } else {
                return (int) mid;
            }
        }
        return (int) right;
    }

Java 代码要注意到:如果中点 mid 声明为 int 类型,针对大整型测试用例通不过,因此变量需要声明为 long 类型

2.袖珍计算器
通常,袖珍计算器通过对数表或其他方式计算指数函数和自然对数。那么考虑将求平方根的运算转换为指数运算和对数运算:

[sqrt{x} = e^{frac{1}{2}logx} ]

代码:

    public int mySqrt(int x) {
        if (x < 2)
            return x;
        int curr = (int) Math.exp(0.5 * Math.log(x)) + 1;//注意判断条件应该是取值+1的平方和x对比
        return (long) curr * curr > x ? curr - 1 : curr;//curr的平方为方便特殊取值应该用long
    }

3.递归+位运算
本方法的思路是使用递归,每一步都减小 x,直到 x < 2。

[sqrt{x} = 2*sqrt{frac{x}{4}} ]

递归式可写成:

[mySqrt(x) = mySqrt(x>>2)<<1 ]

代码:

    public int mySqrt(int x) {
        if (x < 2)
            return x;
        int curr = (mySqrt(x >> 2) << 1) + 1;//因为符号先后的问题原因,记得加括号
        return (long) curr * curr > x ? curr - 1 : curr;
    }

4.牛顿法
牛顿法的思想:切线是曲线的线性逼近。

在迭代过程中,以直线代替曲线,用一阶泰勒展式(即在当前点的切线)代替原曲线,求直线与 x 轴的交点,重复这个过程直到收敛。

牛顿法的内容,建议看如何通俗易懂地讲解牛顿迭代法求开方?数值分析?
借鉴@liweiwei1419的推算:
LeetCode——x 的平方根/有效的完全平方数第1张

代码:

    public int mySqrt(int x) {
        long n = x;
        while (n * n > x) {
            n = (n + x / n) / 2;
        }
        return (int) n;
    }

类似解决:有效的完全平方数

Q:给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。
说明:不要使用任何内置的库函数,如 sqrt。

示例 1:
输入:16
输出:True
示例 2:
输入:14
输出:False

A:
借鉴算平方根的代码。

1.二分法

    public boolean isPerfectSquare(int x) {
        if (x < 2)//特殊用例
            return true;
        long left = 2;//对待特殊用例,例如Integer.MAX_VALUE,使用long,解决求mid的问题
        long right = x / 2;
        while (left <= right) {
            long mid = (left + right) >>> 1;//无符号右移,相当于/2
            long square = mid * mid;
            if (square > x) {
                right = mid - 1;
            } else if (square < x) {
                left = mid + 1;
            } else {
                return true;
            }
        }
        return right * right == x;
    }

2.牛顿法

    public boolean isPerfectSquare(int num) {
        long x = num;
        while(x * x > num){
            x = (x + num / x) / 2;
        }
        return x * x == num;
    }

免责声明:文章转载自《LeetCode——x 的平方根/有效的完全平方数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇解决c# md5与php md5加密不一致的问题(md5(unicode))C++文件fstream的操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java(使用JNA)调用DLL库与C#调用DLL库的对比

前言:在项目中经常使用DLL库对硬件进行操作,在发卡过程中使用频率尤为多,今天就Java与C#中调用DLL库的使用区别做一个介绍,本文着重具体的代码编写,具体过程看以下代码。 前提条件: 笔者已经封装了一个DLL库名为:testdll.dll(具体封库细节,请查阅相关资料),库中包含两个函数: 注:Add为两个整数相加,Sub为两个整数相减。 1.C#...

C++解析(28):异常处理

0.目录 1.C语言异常处理 2.C++中的异常处理 3.小结 1.C语言异常处理 异常的概念: 程序在运行过程中可能产生异常 异常(Exception)与 Bug 的区别 异常是程序运行时可预料的执行分支 Bug 是程序的错误,是不被预期的运行方式 异常(Exception)与 Bug 的对比: 异常 运行时产生除0的情况 需要打...

NOIP2008提高组(前三题) -SilverN

此处为前三题,第四题将单独发布 火柴棒等式 题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自需要两根火柴棍 如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、C>=0) n根火柴棍必...

实现JTable的列宽与内容的自适应

 JTable默认的各列宽度平均,下函数可以实现各列宽度与内容长度适应!来自互联网~ 1 public void FitTableColumns(JTable myTable){ 2 JTableHeader header = myTable.getTableHeader(); 3 int rowCount = myTable.getR...

(转)Android之RemoteViews

RemoteViews中的setxxx方法 比如setCharSequence(int viewId, String methodName, CharSequence value); views.setString(R.id.textview01, "setText", battery + "%"); 其中views是RomoteViews的实例, 第一个...

SQL GUID和自增列做主键的优缺点

我们公司的数据库全部是使用GUID做主键的,很多人习惯使用int做主键。所以呢,这里总结一下,将两种数据类型做主键进行一个比较。 使用INT做主键的优点:     1、需要很小的数据存储空间,仅仅需要4 byte 。     2、insert和update操作时使用INT的性能比GUID好,所以使用int将会提高应用程序的性能。     3、index和J...