如何求解整数平方根

求解一个整数的平方根最简单的办法就是用库函数。

但是如何不用库函数就求解呢?

1. 二分法

我们都知道5的平方根是2.236。如果要求对平方根取整,那么就是2,我们的目的就是在{1,2,3,4,5}这样一个数组中找到2。

这是一个典型的查找的需求,我第一时间想到的查找算法就是二分法。

设left=1,right=5,那么第一趟的mid=3,mid^2=9,大于right,因此我们需要将right左移到mid位置来;

第二趟的left=1,right=3,mid=2,此时mid^2 = 4,基本上接近了,因此判断一下(mid+1)^2,发现9>5,这就能断定出5的平方根取整就是2了,直接返回。

下面是代码的实现:

class Solution {
public:
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    int sqrt(int x) {
        // write code here
        if (x<=0) return 0;
        int left = 1;
        int right = x;
        
        while (left < right)
        {
            long mid = (left+right)/2;
            if (mid*mid > x) 
            {
                right = mid;
            } 
            else if (mid * mid <= x && (mid+1) * (mid+1) > x)
            {
                return mid;
            }
            else 
            {
                left = mid;
            }
        }
        return left;
    }
};

二分法的时间复杂度是O(logN),执行时间也不差:

只用了3ms。

牛顿迭代公式

用牛顿迭代公式求解平方根基本上相当于杀鸡用牛刀。

我们知道平方根实际上就是这样的一个函数:f(x)=x^2-n=0,其实就是求n的过程。

牛顿迭代公式是这样的:

x = x- f(x)/f'(x)

所以带入之前的f(x),我们就能知道求解平方根不过是求解一个公式罢了:

x = x - (x - n/x)/2,其中n是常数。

写成代码就是这样的:

class Solution {
public:
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    int sqrt(int x) {
        // write code here
        double x1=1, x2=0;
        while (abs(x2-x1)> 1e-8)
        {
            x2=x1;//x2用于记录上一次迭代的结果
            x1 = (x1 + x/x1)/2;
        }
        return (int) x1;
    }
};

这个效率就差点了:

posted @ 2021-08-14 15:45  wingsless  阅读(770)  评论(0编辑  收藏  举报