算法面试题: X的平方根

142 阅读2分钟

看下下面这道题:

在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6

public class ArithmeticTest {
    /**
     * 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
     */
    public static void main(String[] args) {

    }


}

这题一共两种解法,分别是二分查找牛顿迭代,老规矩先理思路.

二分查找

image.png

编码如下

public class ArithmeticTest {
    /**
     * 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
     */
    public static void main(String[] args) {
        int x = 37;
        int result = binarySearch(x);
        System.out.println("结果为:" + result);
    }

    private static int binarySearch(int x) {
        //为什么指针要从-1开始? 因为  0 和1 都可能是返回值
        int index = -1;
        int left = 0;
        int right = x;
        //什么时候跳出循环? left右移,right左移,当两个指针相撞时,循环结束
        while (left <= right) {
            //二分位置的值
            int mid = left + (right - left) / 2;

            if (mid * mid <= x) {
                //当中间值的平方小于等于x时,指针右移
                index = mid;
                left = mid + 1;
            } else {
                //反过来right左移
                right = mid - 1;
            }
        }
        return index;
    }


}

输出结果:

image.png

牛顿迭代

image.png

还是直接看编码吧.

public class ArithmeticTest {
    /**
     * 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
     */
    public static void main(String[] args) {
        int x = 37;
        int result = newTon(x);
        System.out.println("结果为:" + result);
    }
    //牛顿迭代
    private static int newTon(int x) {
        //等于0直接返回,否则算法会报错
        if (x == 0) {
            return 0;
        }
        //x/2  这个值 随便传 传x也可以,不过为了减少递归次数,最好给个近似值
        return (int) sqrt(x / 2, x);
    }

    private static double sqrt(double i, int x) {
        // 声明结果
        double result = (i + x / i) / 2;
        // 运算到 double精度极限就可以返回
        if (result == i) {
            return i;
        } else {
            //递归
            return sqrt(result, x);
        }
    }

    private static int binarySearch(int x) {
        //为什么指针要从-1开始? 因为  0 和1 都可能是返回值
        int index = -1;
        int left = 0;
        int right = x;
        //什么时候跳出循环? left右移,right左移,当两个指针相撞时,循环结束
        while (left <= right) {
            //二分位置的值
            int mid = left + (right - left) / 2;

            if (mid * mid <= x) {
                //当中间值的平方小于等于x时,指针右移
                index = mid;
                left = mid + 1;
            } else {
                //反过来right左移
                right = mid - 1;
            }
        }
        return index;
    }


}

打印结果

image.png