leetcode-69. 平方根Sqrt(x)

347 阅读2分钟
/**
 * ref:https://leetcode-cn.com/problems/sqrtx/description/
 * 给你一个非负整数x ,计算并返回x的算术平方根。
 * 由于返回类型是整数,结果只保留整数部分,小数部分将被舍去 。
 * 注意:不允许使用任何内置指数函数和算符,例如pow(x, 0.5)或者x**0.5。
 * 示例 1:
 * 输入:x = 4
 * 输出:2
 * 示例 2:
 * 输入:x = 8
 * 输出:2
 * 解释:8的算术平方根是2.82842..., 由于返回类型是整数,小数部分将被舍去。
 **/
public class SqrtxFind {

    public static void main(String[] args){
        System.out.println(bruteForceSearch(0));
        System.out.println(binarySearch(99));
    }

    /**
     * 暴力破解法:
     * 平方根就是寻找一个i,使得i*i=x,则表明x的平方根是i。
     * 从0~x/2进行迭代,遍历出i*i<=x,且(i+1)*(i+1)>x,则i就是找到的平方根的整数部分
     * @param x
     * @return
     */
    public static int bruteForceSearch(int x){
        for(int i=0;i<=x/2;i++){
            if(i*i<=x&&(i+1)*(i+1)>x){
                return i;
            }
        }
        return -1;
    }

    /**
     * 二分查找法:
     * 从0~x/2进行迭代,遍历出i*i<=x,且(i+1)*(i+1)>x,则i就是找到的平方根的整数部分。
     * 在迭代时候,采用的是二分查找法。
     * 第一步:将0作为左侧开始,将x/2作为右侧的结束。
     * 第二步:在区间[0,x/2]取中间值=左侧值+右侧值之和的一半=(0+x/2)/2
     *  进行比较,如果中值平方大于x,则值应该是在左侧,即右侧值-1,继续迭代。
     *  如果中值平方小于等于x,则值应该是在右侧,既左侧值+1,进行迭代。
     *  当左侧值>右侧值时,迭代就结束。如果在此过程中找到中值平方小于等于x,则最后一次找到的就是算术平方根。
     * @param x
     * @return
     */
    public static int binarySearch(int x){
        int left = 0;
        int right = x/2;
        int index = -1;
        // 二分查找到,左侧的值小于等于右侧的值时进行迭代
        while(left<=right){
            int mid = (left+right)/2;
            // 如果mid的平方小于x,此时如果下一个值平方大于x,则mid就是平方根
            // 如果mid的平方小于x,则mid就是平方根
            // 合并上述逻辑,就是mid的平方最大值小于或等于x,则mid就是平方根
            if(mid*mid<=x) {
                index = mid;
                left = mid+1;
                // 如果mid的平方大于x,此时需要将右侧值-1,继续计算。
            }else {
                right = mid-1;
            }
        }
        return index;
    }
}