69. Sqrt(x)*

本文详细解析了LeetCode上的经典题目69.Sqrt(x),提供了两种高效求解平方根的方法:二分法和牛顿法。通过C++代码实现,展示了如何避免整数溢出并达到最优性能。

69. Sqrt(x)*

https://leetcode.com/problems/sqrtx/

题目描述

Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:

Input: 4
Output: 2

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since 
             the decimal part is truncated, 2 is returned.

解题思路

思路 1: 二分法, 在 [0, x / 2] 范围内进行搜索, 找到第一个使得 mid * mid > x 的数. 注意 mid * mid 可能越界的问题, 解决方法可以用 longlong long, 或者变换成 mid > x / mid.

思路 2: 牛顿法.

C++ 实现 1

这个实现 beats 100%.

使用二分查找可解. 但有个地方必须注意:

判断条件不要写成

if (mid * mid <= x)

而是要写成 if (mid <= x/mid), 因为当 mid 足够大时, mid * mid 超出了 int 能表示的范围.

class Solution {
public:
    int mySqrt(int x) {
        int l = 1, r = x;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (mid <= x/mid)
                l = mid + 1; // 注意 l 不是 l++ 变化!!!
            else
                r = mid - 1;
        }
        return (l - 1); // 最后 l 找到的是第一个满足 mid * mid > x 的值.
    }
};

C++ 实现 2

关于牛顿法, 参见:

公式是: x i + 1 = 1 2 ( x i + n x i ) x_{i+1} = \frac{1}{2}(x_i + \frac{n}{x_i}) xi+1=21(xi+xin) (n 就是这里的 x)

注意下面代码中, res 设置为 long 是为了防止越界, 因为 res + res / 2 在初始化 res = x 的情况下, 如果 x 刚好为 INT32_MAX, 那么就越界了.

class Solution {
public:
    int mySqrt(int x) {
        if (x < 1) return 0; 
        long res = x;
        while (res > x / res)
            res = (res + x / res) / 2;
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值