leetcode 69. x 的平方根

问题描述

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

问题分析

方法一是使用牛顿法,设\(f(x) = x^2 - a, f(x0) + f'(x0)(x-x0) = 0\),则\(x = (x0*x0+a)/(2*x0)\).

方法二是使用二分法,如果mid*mid=x,则mid即为所求,如果mid*mid<x并且(mid+1)*(mid+1)>x,则根据规则mid即为所求,如果mid*mid>x,则中间值过大,right=mid-1,如果mid*mid<x并且(mid+1)*(mid+1)<x,则mid值过小,left=mid+1.

注意一个技巧是如果\(0\leq x \leq 1,z\in \mathbb{Z}\),则\(\sqrt x=x\), 如果\(2\leq x \leq 3\),则\(\sqrt x = 1\),如果\(x \geq 4, x \in \mathbb{Z}\), 则 \(\sqrt x \leq x/2\).

代码1

class Solution {
public:
    int mySqrt(int x) {
        if(x <= 1) return x;
        //else if(1 < x && x < 4) return 1;//这一步可以注释掉,因为2<=x<=3时,\sqrt{x}=1=x/2
        long x0 = x/2;
        while(x0*x0 > x)
        {
            x0 = (x0*x0 + x)/(2*x0);
        }
        return x0;
    }
};

结果1

执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗 :8.1 MB, 在所有 C++ 提交中击败了81.46%的用户

代码2

class Solution {
public:
    int mySqrt(int x) {
        if(x <2) return x;
        int left = 1,right = x/2;
        long middle,tmp1,tmp2;
        while(left <= right)
        {
            middle = left + (right - left)/2;
            tmp1 = middle*middle;
            tmp2 = (middle+1)*(middle+1);
            if(tmp1 == x)break;
            else if(tmp1 < x && tmp2 > x)break;
            else if(tmp1 > x) right = middle - 1;
            else left = middle + 1;
        }
        return middle;
    }
};

结果2

执行用时 :4 ms, 在所有 C++ 提交中击败了84.10%的用户
内存消耗 :8.3 MB, 在所有 C++ 提交中击败了17.31%的用户
posted @ 2020-02-08 09:00  曲径通霄  阅读(106)  评论(0编辑  收藏  举报