69.x 的平方根(二分查找)

356 阅读2分钟

「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」。

每日刷题第51天 2021.02.23

x 的平方根

题目

  • 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
  • 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
  • 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者x ** 0.5

示例

  • 示例1
输入: x = 4
输出: 2
  • 示例2
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

提示

  • 0 <= x <= 2^31 - 1

拓展

  • 二分查找:在有序表中查找元素常常使用二分查找(Binary Search),有时也叫“折半查找”。
  • 逐步缩小范围是一种常见的二分查找解题思维逻辑。其把原序列划分成元素个数尽量接近的两个子序列,然后再进行递归查找。
  • 时间复杂度:O(logn)

二分查找

  • 常听大家说,二分看起来很简单,但是做对很难。因为细节很多,比如边界问题就非常棘手。
  • 下面最新学习的这个二分模板,成功的规避了边界问题。取l = 0, r = n,也就是取整个数组的两个外边界点。那么while循环的判断条件l + 1 != r,表示:l、r最终不会重叠,则不会产生边界问题,最终只需要自己根据题目选择l还是r
  • 注意:边界l = 0,r = n并不是固定的,举例:
    • 比如当前的数组长度为:2 <= nums <= 8,那么l = 1,r = 9

解法

  • 下题解法就是使用:二分最易理解的模板
/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function(x) {
  let l = -1n;
  // 声明一个bigint数据
  let r = BigInt(x + 1);
  // console.log(r);
  let m;
  while(l + 1n != r){
    m = (l + r) / 2n;
    if(m * m <= x){
      l = m;
    }else {
      r = m;
    }
  }
  return l;
};