二分查找-69.x的平方根

题目描述

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

69. x 的平方根 - 力扣(LeetCode)

思路讲解

计算非负整数x的算术平方根的整数部分,如果不使用任何内置的指数函数或算符,我们可以采用暴力解法(也称为直接法或枚举法)。这种方法的基本思路是从0开始逐个尝试,直到找到一个数,其平方不超过x,并且这个数的下一个数的平方会大于x

int mySqrt(int x) {  
    if (x == 0) return 0; // 特殊情况处理  
  
    for (int i = 1; i <= x; ++i) {  
        if (i * i <= x && (i + 1) * (i + 1) > x) {  
            // 找到i,使得i*i <= x且(i+1)*(i+1) > x  
            // 直接返回i即可,因为题目要求只保留整数部分  
            return i;  
        }  
    }  
  
    // 理论上这行代码不会被执行到,因为上面的循环肯定会找到满足条件的i  
    // 但为了代码的完整性,还是加上这一行  
    return -1; // 返回一个不可能的值,表示出错(实际上这种情况不会发生)  
}  
  

但是,直接遍历从0到x的所有数是非常低效的。为了计算非负整数x的算术平方根的整数部分,我们可以采用二分查找法。考虑到平方根的性质,我们可以设定一个查找范围从0到x(因为x的平方根肯定小于或等于x),并在这个范围内进行二分查找。

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

实现步骤:

  1. 边界条件检查
    • 首先,函数检查输入 x 是否小于 1。如果是,那么 x 的平方根整数部分必然是 0(因为 0 和 1 的平方根整数部分都是 0),所以直接返回 0。
  2. 初始化二分查找的边界
    • 接着,函数初始化两个指针(或索引)left 和 right,分别指向查找范围的左右边界。由于平方根的值至少为 0(对于非负整数 x),且最大不超过 x(因为 sqrt(x) * sqrt(x) = x),所以 left 被初始化为 1(因为 0 的情况已经在边界条件中处理过了),right 被初始化为 x
  3. 执行二分查找
    • 函数进入一个 while 循环,条件是 left < right。这个循环会一直执行,直到 left 和 right 相等,此时它们就指向了平方根的整数部分(或者比它大1的最小整数,但在接下来的步骤中会被正确处理)。
    • 在每次循环中,函数计算中点 mid。这里使用了 long long 类型来存储 mid,以防止在计算 mid * mid 时发生整数溢出。计算 mid 时使用了 (right - left + 1) / 2,这实际上是一种“向上取整”的除法操作(在整数除法中),但它在这里的主要作用是确保当 left 和 right 相邻时,mid 会等于 right(从而避免无限循环)。
    • 然后,函数检查 mid * mid 与 x 的关系:
      • 如果 mid * mid <= x,说明 mid 可能是我们要找的平方根的整数部分(或者比它大),所以将 left 更新为 mid,继续在右半部分查找。
      • 如果 mid * mid > x,说明 mid 太大了,所以将 right 更新为 mid - 1,在左半部分继续查找。
  4. 返回结果
    • 当 while 循环结束时,left 和 right 相等,且它们指向了平方根的整数部分(因为我们在每次循环中都将范围缩小了,直到无法再缩小为止)。所以,函数返回 left(或 right,因为此时它们是相等的)作为结果。
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中的解释,一个数的平方根最多不会超过它的一半。所以对于69这个数,它的平方根最多不会超过34.5。为了计算出精确的平方根值,我们可以使用引用中提到的求解方程f(x) = x^2 - a的正根的方法。根据引用,我们可以实现一个函数sqrt(x),来计算并返回x的平方根,其中x是非负整数并且返回类型是整数。根据引用中的方法,我们可以使用二分法来逐步逼近平方根的值。具体步骤如下: 1. 设定左边界low为0,右边界high为x。 2. 当low小于等于high时,执行以下步骤: a. 计算中间值mid,即mid = (low + high) / 2。 b. 如果mid的平方等于x,返回mid作为x的平方根。 c. 如果mid的平方大于x,将high更新为mid - 1。 d. 如果mid的平方小于x,将low更新为mid + 1。 3. 返回low - 1作为x的平方根。 根据以上步骤,我们可以得到69平方根为8。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【LeetCode】69. x 的平方根](https://blog.csdn.net/weixin_41888257/article/details/108357200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【Leetcode刷题笔记】69. x的平方根](https://blog.csdn.net/xqh_Jolene/article/details/124820855)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [leetcode : 69. x 的平方根](https://download.csdn.net/download/angelloveyou/10675944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值