LeetCode 148. x的平方根(二分法;牛顿迭代法)

2021年06月07日 周一 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】



1. x为非负整数

1.1 返回整数

这时稍微简单点,用二分法即可,唯一需要注意的就是越界问题。

class Solution {
public:
    int mySqrt(int x) {
        if(x==0 || x==1) return x;
        int l=1, r=x;
        while(l<r){
            int m=l+(r-l+1)/2; // l 从 1 开始,不然 r+1 可能会越界
            if(m>x/m) r=m-1; // 这里写成 m*m>x 也可能会越界,所以写成 m>x/m
            else if(m==x/m) return m;
            else l=m;
        }
        return l;
    }
};

1.2 返回浮点数

1.2.1 二分法(不保证正确)

返回浮点数的话,最好用double,精度高,而且不用担心越界。

注意:要搞清楚题意,是要求误差小于e,还是精确到小数点后几位。

我感觉这两种描述不一样,但是也找不出它们之间的关系。如果题目要求精确到小数点后几位,就按照误差小于e来计算吧!

精确到小数点后3位表示误差小于0.001?

2023.11.16 @如三月兮 误差小于0.001,表示小数点后三位是固定下来了,假设2.6768,676此时刚固定下来, 下一次迭代得到的数是2.6765,这两个数的误差是0.0003<0.001满足条件退出迭代,返回的是2.676,
这时只能说明小数点后3位固定是精确的,再往后迭代误差绝对小于0.001,但是第4位不固定

double my_sqrt(int x) {
	if (x == 0 || x == 1) return x;
	const double e = 1e-8; 
	double dx = x;
	double l = 1., r = dx, m = l + (r - l) / 2.; // 这里要除以一个浮点数
	while (fabs(m * m - dx) >= e) {
		if (m * m - dx >= e) r = m - e;
		else l = m + e;

		m = l + (r - l) / 2.;
	}
	return m;
}

1.2.2 牛顿迭代法(推荐)

返回浮点数的话,最好还是用牛顿迭代法,收敛更快,而且准确性也高。
在这里插入图片描述
在这里插入图片描述

double mySqrt(int x) {
	if (x == 0) return x;
	const double e = 1e-8;
	double C = x, x0 = x;

	do {
		x0 = 0.5 * (C / x0 + x0);
	} while (fabs(x0 * x0 - x) >= e);

	return x0;
}

2. x为浮点数

直接用牛顿迭代法吧。

double mySqrt(double x) {
	if (x == 0.0) return x;
	const double e = 1e-8;
	double C = x, x0 = x;

	do {
		x0 = 0.5 * (C / x0 + x0);
	} while (fabs(x0 * x0 - x) >= e);

	return x0;
}

3. 总结

除了返回整数的,其它情况都推荐用牛顿迭代法!


参考文献

https://leetcode-cn.com/problems/sqrtx/solution/x-de-ping-fang-gen-by-leetcode-solution/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值