全栈开发知识库

105.x 的平方根

题目

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

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

示例 1:

  • 输入:x = 4
  • 输出:2

示例 2:

  • 输入:x = 8
  • 输出:2

解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

思路

我们在猜一个数 mid,看 mid × mid 会不会超过 x。

如果: - mid × mid == x,说明刚好猜中 - mid × mid < x,说明 mid 可能是答案,但还可以试试更大的 - mid × mid > x,说明 mid 太大了,要往小了猜 这就是二分查找。
为了避免 mid * mid 太大导致溢出,我们不用 mid * mid <= x,而用:
mid <= x / mid
意思完全一样,但更安全。

class Solution {
    fun mySqrt(x: Int): Int {
        // 0 和 1 的平方根就是它自己
        if (x < 2) return x

        var left = 1
        // 最大不可能超过中间的数
        var right = x / 2
        var answer = 0

        // 在 left 到 right 之间不断猜答案
        while (left <= right) {
            // 取中间值
            val mid = left + (right - left) / 2

            // 如果 mid <= x / mid
            // 说明 mid * mid <= x
            // mid 没有超过平方根,可能是答案
            if (mid <= x / mid) {
                answer = mid

                // 继续往右找,看有没有更大的合法答案
                left = mid + 1
            } else {
                // 说明 mid * mid > x
                // mid 太大了,要往左找
                right = mid - 1
            }
        }

        return answer
    }
}

复杂度

  • 时间复杂度: O(log x),二分查找次数约为 log₂ x。
  • 空间复杂度: O(1)。


  • 邮箱 :charon.chui@gmail.com
  • Good Luck!
本页由 Markdown 自动渲染 · 共 628 篇笔记