算法---LeetCode 69. x 的平方根

1. 题目

原题链接

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

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

Related Topics 数学 二分查找
👍 688 👎 0

2. 题解

2.1 解法1: 二分法

  1. 在 [0…x] 闭区间搜索该元素,
  2. 注意二分查找中几个关键点的写法:
  • 注意 mid*mid 可能存在数值越界问题, 要将其转化为 long类型
  • 注意初始条件 left=0, right=x
  • while循环条件 (left<right) : 一般习惯不含等于
  • mid 中点的选取, 若 mid = left + (right - left) / 2, 则为向下取整
  • 边界收缩是 mid 还是 mid + 1, 若 mid 向下取整, 则 left的情况需要 mid+1, 向右需要加 1, 可以考虑只有两个元素的情况, 如果 left==mid, 则永远跳不出循环
  • 循环结束落点的判断: 同样思考两个元素的情况, 如 x=8, 最后 left=2, right=3, 那么最后会落在 3 上, 所以返回结果需要减一

注意点:

  • left , right 使用 long 类型 避免平方超界
  • 相当于查找最后一个 mid 的平方 小于 x 的值, 所以向上取整, 使用 (right - left + 1) / 2 + left , 同时 == 的情况要分开讨论
    class Solution {
        public int mySqrt(int x) {
            if (x == 0 || x == 1) return x;
            long left = 0, right = x;
            while (left < right) {
                long mid = (right - left + 1) / 2 + left;
                long temp = mid * mid;
                if (temp == x) {
                    return (int)mid;
                } else if (temp < x) {
                    left = mid;
                } else {
                    right = mid - 1;
                }
            }
            return (int)left;
        }
    }

写法2:

    class Solution {
        public int mySqrt(int x) {
            if (x == 0 || x == 1) {
                return x;
            }
            int left = 0, right = x;
            while (left < right) {
                // 这里是向下取整
                int mid = left + (right - left) / 2;
                long temp = (long) mid * mid;
                if (temp == x) {
                    return mid;
                } else if (temp < x) {
                    // 因为mid 计算时向下取整, 所以左边界需要加 1, 可以考虑只有两个元素的情况, 如果 left==mid, 则永远跳不出循环
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            // 最后需要考虑落在的元素是否是答案, 可能会相差1
            return left - 1;
        }
    }

参考: 二分查找(Java)

2.2 解法2: 牛顿迭代法

  1. 每次根据导数公式计算结果 t, 若 t*t-x < 1, 误差小于1, 即可返回结果
    设结果为 ans, ans=(ans + C / ans ) /2, 其中 C 为任意数, 一般取 x

拓展: 若要求精确到0.001, 类似这种, 只需将 1 改成相应的精度即可
注意:
1.循环的条件 为 >=, 就继续循环
2.记住公式 t=(t+x/t)/2

    class Solution {
        public int mySqrt(int x) {
            if (x == 0 || x == 1) {
                return x;
            }
            double t = x;
            while (t * t - x >= 1) {
                t = (t + x / t) / 2;
            }
            return (int)t;
        }
    }

官方题解
牛顿迭代法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值