LeetCode每日一题之x的平方根

前言

大家好,今天是LeetCode每日一题的第五天,给大家分享的是 寻找数组的中心下标,难度系数两颗星!废话不多数,先上题目!

1.1 题目要求

题目类型x的平方根

题目要求:在不使用sqrt(x)函数的情况下, 得到x的平方根的整数部分

特别提醒:Java中的sqrt()函数用于求平方根

重点考查二分法牛顿迭代

1.2 解题方法

1.2.1 二分法查找
1.解题思路

二分法查找暴力算法的基础上进行改进得到的,所有我们需要首先了解一下暴力算法的思路

暴力算法

由题意知, x的平方根应该在2到x-1之间(即满足 2 < x的平方根 < x-1);假设遍历到了第i个数, 满足 i < x的平方根, 左右两边同时求平方, 即转换为 i * i < x, 并且同时满足 i+1 > x的平方根, 左右两边同时求平方, 即转换为 (i+1) * (i+1) > x;

因此我们只需判断 i * i 和 (i+1) * (i+1) 哪个更接近 x值即可, 更接近前者, 那么x的平方根整数部分就为 i; 否则为i+1;

二分法查找

设置两个左右指针left和right

left -> <-right
[2,3,4,…,x-1]

到某一时刻, 左右指针会重合, 该位置为中间值, 此时循环结束

left ->mid<-right
[2,3,4,…,x-1]

2.代码实现
  • 测试代码
package com.kuang.leetcode5;

/**
 * @ClassName SqrtX
 * @Description x的平方根
 * @Author 狂奔の蜗牛rz
 * @Date 2021/8/23
 */
public class SqrtX {

    //主方法测试
    public static void main(String[] args) {
        //使用二分查找法获取x平方根的整数部分值
        //输入: 24 预测结果: 4
        System.out.println("使用二分查找, x的平方根整数部分为:"+binarySearch(24)); // 真实结果: 4
    }

    /**
     * 使用二分查找x的平方根整数部分
     * @param x 求平方根的x
     * @return x的平方根整数部分
     */
    public static int binarySearch(int x) {
        /**
         * index为x平方根的整数部分值(-1表示该值不存在),
         * left为左指针(从左侧开始移动, 因此初值为左侧边界起始值0),
         * right为右指针(从右侧开始移动, 因此初值为右侧边界值x)
         */
        int index = -1, left = 0, right = x;
        //while循环的执行条件为left(左指针)值是否小于等于right(右指针)(即左指针在右指针左侧, 直至两者重合)
        while(left <= right) {
            //mid中心值
            int mid = left + (right-left)/2;
            /**
             * 为什么mid = left + (right-left)/2 ?
             * 原因如下:
             * 初始状态:
             *  0(left初值)          x(right初值)
             *  ------------------>
             *  left ->         <- right
             *
             *  左右指针移动后:
             *  ------|-----|----|---->
             *     left    mid  right
             *        |<-------->|
             *         right-left
             *        |<--->|
             *
             * mid值为:
             *  ------|-----|----|---->
             *     left    mid  right
             * |<--->|<--->|
             *   left + (right-left)/2 = mid
             */
            //判断mid(中心值)是否小于等于x的平方根(这里使用mid*mid<=x, 等同于mid(中心值)小于等于x的平方根)
            if(mid * mid <= x) {
                //若mid(中心值)小于等于x的平方根, 则将mid赋值给index(平方根整数部分)
                index = mid;
                //然后left(左指针)值加1(即左指针向右移动一位)
                left = mid + 1;
            } else {
                //若mid(中心值)小于等于x的平方根, 则right(右指针)值加1(即右指针向左移动一位)
                right = mid - 1;
            }
        }
        //最后将index(x的平方根整数部分)返回
        return index;
    }

}
  • 测试结果

在这里插入图片描述

结果测试结果与预测一致!

1.2.2 牛顿迭代法
1.解题思路

存在已知数x,其值为整数i的平方,即i * i = x ,转化一下为i/n = n, 即i = x的平方根

例如x为12, 12的一对组合因子为 2 * 6, 即 2 * 6 = 根号12 * 根号12, 让2和6取平均值, 即 (2+6)/2= 8/2 =4, 而这一对组合因子都求平方后, 即2 * 2 = 4, 6 * 6 = 36;4求平方后为16(4 * 4), 而x值为12, 4 < 12 < 16 < 36, 16比4和36都要更接近12;

根据上面可以推出公式: (2+6)/2 => (12/6 + 6) => (x/i + i)/2

  • 因此只需判断 x/i = i 等式是否成立, 然后求n的值即可;
  • 求出n值后, 再代入到(x/i + i)/2中得出的结果便是x的平方根整数部分
  • 如果等式一直不成立, 就一直递归(x/i + i)/2, 直到等式成立
2.代码实现
  • 测试代码
package com.kuang.leetcode5;

/**
 * @ClassName SqrtX
 * @Description x的平方根
 * @Author 狂奔の蜗牛rz
 * @Date 2021/8/23
 */
public class SqrtX {

    //主方法测试
    public static void main(String[] args) {
        //输入: 24 预测结果: 4
        System.out.println("使用牛顿迭代, x的平方根整数部分为:"+newton(24)); //测试结果: 4
    }

    /**
     * 使用牛顿迭代法获取x的平方根整数部分
     * @param x 求平方根的x
     * @return 平方根x的整数部分
     */
    public static int newton(int x) {
        //判断x是否等于0
        if(x == 0) {
           //若x等于0, 返回值为0
           return 0;
        }
        //否则将sqrt方法的结果(该结果为x的平方根整数部分)进行返回
        return (int)sqrt(x,x);
    }

    /**
      求x的平方根整数部分
     * @param i 被x取整的数
     * @param x 求平方根的x
     * @return
     */
    public static double sqrt(double i, int x) {
        /**
         * x的平方根整数部分值为(x/i + i)/2,
         * 最终需要将这个结果返回, 将其存入到res变量中
         */
        double res = (i + x/i)/2;
        //判断res(返回值)是否与i值相等(在不断递归的过程中res和i会越来越接近)
        if(res == i) {
            //将i值返回
            return i;
        } else {
            //若res返回值不等于i, 继续调用当前方法(直至res和i值相等)进行递归
            return sqrt(res, x);
        }
    }

}
  • 测试结果

在这里插入图片描述

结果测试结果与预测一致!


好了,今天LeetCode每日一题—x的平方根到这里就结束了,欢迎大家学习和讨论,点赞和收藏!


参考视频链接:https://www.bilibili.com/video/BV1Ey4y1x7J3 (国内算法宝典-LeetCode算法50讲)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔の蜗牛rz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值