X 的算术平方根怎么求?

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情


大家好呀,我是你们的算术蛋。

今天解决算术平方根 Sqrt(x) ,通过这道常见面试题作为二分查找实战系列开篇。

咱们话不多说,赶紧开整。

69-0

LeetCode 69:Sqrt(x)

题意

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

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

示例

输入:x = 8

输出:2

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

提示

  • 不允许使用任何内置指数函数和算符
  • 0 <= x <= 2^31 -1

题目解析

水题,难度简单,面试中的常见题

这道题当然不能使用 pow(x, 0.5) 或 x ** 0.5 等内置函数,不然就没了考察的意义。

对于本题,是对非负整数 x 开根号,即 y = sqrt(x)。

69-1

这是一个单调递增函数。

而我在【ACM 选手带你玩转二分查找! 】文章中讲过,二分查找的使用,要有一个前提条件要查找的数必须在一个有序数组里

这道题的条件正好满足单调递增,并且 sqrt(x) 返回的是整数 res,而 res 是满足 res * res <= x 的最大值,所以可以用二分查找来解决。

明白了这些剩下的就是常规操作:

  • 确定二分查找的上界 high = x 和下界 low = 0。
  • 比较 mid * mid 与 x 的关系,动态调整 [low, high]。

图解

以 n = 8 为例,为了方便大家理解,我把从 low ~ high 之间所有的数都列出来。

69-2

low, high, res = 1, x, -1

第 1 步,x = 8,low = 1,high = 8,mid = (low + high) // 2 = 4:

69-3

mid = (low + high) // 2

此时 mid * mid = 16 > x,则 high 向左移动至 mid - 1 = 3 处。

69-4

if mid * mid > x:
      high = mid - 1

第 2 步,x = 8,low = 1,high = 3,mid = (low + high) // 2 = 2:

69-5

此时 mid * mid = 4 <= x,则 res = mid = 2,low 向右移动至 mid + 1 = 3 处。

69-6

if mid * mid <= x:
    res = mid
    low = mid + 1

第 3 步,x = 8,low = 3,high = 3,mid = (low + high) // 2 = 3:

69-7

此时 mid * mid = 9 > x,则 high 向左移动至 mid - 1 = 2 处。

此时 low > high,循环终止,输出 res = 2。

本题题解使用二分查找 res,查找的长度为 x,所以时间复杂度为 O(logx)

额外创建了 low、high 指针及 res 存储结果,所以空间复杂度为 O(1)

代码实现

Python 代码实现

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x == 0 or x == 1:
            return x
​
        low, high, res = 1, x, -1
​
        while low <= high:
            mid = (low + high) // 2
            if mid * mid <= x:
                res = mid
                low = mid + 1
            else:
                high = mid - 1
​
        return res

Java 代码实现

class Solution {
    public int mySqrt(int x) {
        int low = 0, high = x, res = -1;
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if ((long) mid * mid <= x) {
                res = mid;
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        return res;
    }
}

图解 Sqrt(x) 到这就结束辣,看了之后是不是觉得还挺简单的?

不过,上一篇文章我讲了二分查找,看到这道题的时候你有第一反应用二分查找去解决嘛?

AC 不是目的,目的是好好去琢磨琢磨这种解题方法,然后能运用到之后的题目中。

记得帮我点赞呀,么么哒。

我是帅蛋,我们下次见。

猜你喜欢

转载自juejin.im/post/7111918957036208136
今日推荐