算法 x的平方根(二分法、牛顿迭代法)

前言

题目链接

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:

输入:x = 4
输出:2
示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。


一、二分法

1.1

二分法不做赘述,代码如下:

// 二分法
int mySqrt(int x){
    int index = -1;  // 因为 0/1都可能是结果,所以 -1 用来表示不可能的结果
    int left = 0, right = x;
    long mid;

    while(left <= right)
    {
        mid = left + (right - left)/2;
        if(mid * mid <= x)  // 此处 mid*mid的类型是int,可能会导致溢出。所以mid的类型要为long
        {
            index = mid;
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }

    return index;
}

二、牛顿迭代法

2.1

假设平方根是 i,则 i 和 x/i 必然都是 x 的因子,而 x/i 必然等于 i,推导出 i + x/i = 2 * i,得出 i = (i + x/i) / 2。

由此得出解法,i 可以任选一个值,主要上述公式成立,i 必然是 x 的平方根,如果不成立,(i + x/i) / 2得出的值进行递归,直至得出正确解。

为什么“(i + x/i) / 2得出的值进行递归,就能得出正确解”?

假设求 12 的平方根,我们令 i 等于12。这样的话,(i + x/i) / 2 = (12 + 12/12)/ 2 = 13 / 2 = 6.5,c语言中对 6.5 类型转换为 int,结果就是 6。此时,6 相比 12(i)和 1(12/12)更接近 12 的平方根。

接着把 6 赋值给 i,得到 (i + x/i) / 2 = (6 + 12/6)/ 2 = 8 / 2 = 4。此时,4 相比 6(i)和 2(12/6)更接近 12 的平方根(2 的平方是 4,6 的平方是 36,而 4 的平方是 16,最接近 12)。即两个因子的均值更接近其平方根。

最终代码如下:

// 牛顿迭代法
double squart(double i, int x)
{
    double res = (i + x/i)/2;  // res 比 i 更接近 x 的平方根
    if(res == i)
    {
        return i;
    }
    else
    {
        return squart(res, x);
    }
}

int mySqrt(int x){
    if(x == 0 || x == 1) return x;

    return (int)squart(x, x);  // x的取值只会影响计算次数,取什么值无所谓。
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值