数组(2):69.Sqrt(x)

数组(2):69.Sqrt(x),第1张

数组(2):69.Sqrt(x)

题目链接:

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

题目

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

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

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


示例 1:

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

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

方法:

二分法

第一次代码: 
class Solution {
    public int mySqrt(int x) {
        int mid = x / 2;

        while(true){
            if(mid * mid <= x && (mid+1) * (mid+1) > x)
                return mid;
            else if(mid * mid > x)
                mid /= 2;
            else 
                mid += 1;
        }
    }
}

报错:输入2147395599,输出1073788163,预期输出46339


原因:int类型最大值 ,当mid*mid时有一部分超出了int的范围。

改进代码1:
class Solution {
    public int mySqrt(int x) {
        long mid = x / 2;

        while(true){
            if(mid * mid <= x && (mid+1) * (mid+1) > x)
                return (int)mid;
            else if(mid * mid > x)
                mid /= 2;
            else 
                mid += 1;
        }
    }
}

执行用时:19 ms    内存消耗:39.1MB

改进代码2:
// 二分法,算术平方根一定在 [1,x] 之间,所以以 1 ~ x 为界

class Solution {
    public int mySqrt(int x) {
        long first = 1, last = x, mid = 0, ans = 0;

        while(first <= last){
            mid = (first + last) / 2;
            if(mid * mid <= x){
                ans = mid;
                first = mid + 1;
            }
            else
                last = mid - 1;
        }
        return (int)ans;
    }
}

执行用时:1 ms    内存消耗:39.1 MB

改进代码3: 
// 二分法,算术平方根一定在 [1,x] 之间,所以以 1 ~ x 为界

// 这里用 x/mid 来替代 mid*mid ,使得int类型也足够了,不需要long类型

class Solution {
    public int mySqrt(int x) {
        int first = 1, last = x, mid = 0, ans = 0;

        while(first <= last){
            mid = (first + last) / 2;
            if(x / mid >= mid){
                ans = mid;
                first = mid + 1;
            }
            else
                last = mid - 1;
        }
        return ans;
    }
}

牛顿迭代法:
// 牛顿迭代法  (x0 = (c + c / x) / 2 )== c ? (return c) : (c = x0)

class Solution {
    public int mySqrt(int x) {
        double c = x, x0 = 0;

        if(x == 0)    // 分母为0时单独考虑
            return 0;
        while(true){
            x0 = (c + x/c) / 2;
            if(c == x0)
                return (int)c;
            else
                c = x0;
        }
    }
}

 答案链接:https://leetcode-cn.com/problems/sqrtx/solution/niu-dun-die-dai-fa-by-loafer/

类似题目:367. 有效的完全平方数

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5713748.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存