您的位置:首页 > 娱乐 > 八卦 > 二分查找-69.x的平方根

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

2024/12/23 6:30:05 来源:https://blog.csdn.net/2302_80190174/article/details/141361716  浏览:    关键词:二分查找-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,因为此时它们是相等的)作为结果。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com