本文主要是介绍Leetcode 剑指 Offer II 072.x 的平方根,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目难度: 简单
原题链接
今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复
剑指offer2
就能看到该系列当前连载的所有文章了, 记得关注哦~
题目描述
给定一个非负整数 x ,计算并返回 x 的平方根,即实现 int sqrt(int x) 函数。
正数的平方根有两个,只输出其中的正数平方根。
如果平方根不是整数,输出只保留整数的部分,小数部分将被舍去。
示例 1:
- 输入: x = 4
- 输出: 2
示例 2:
- 输入: x = 8
- 输出: 2
- 解释: 8 的平方根是 2.82842…,由于小数部分将被舍去,所以返回 2
提示:
- 0 <= x <= 2^31 - 1
题目思考
- 如何优化时间复杂度?
解决方案
思路
- 分析题目, 最容易想到的思路就是从 0 开始遍历, 判断当前数字的平方是否大于 x, 是的话就返回当前数字减 1
- 不过这样时间复杂度达到了
O(sqrt(x))
, 如何优化呢? - 对于区间
[0,x]
而言, 其每个数字的平方都满足单调递增, 我们可以利用这一点, 采用二分查找的方式加速 - 也就是二分查找平方值小于等于 x 的最大整数, 因为实际平方根可能是小数, 而题目要求只保留整数部分, 所以对应整数的平方不一定恰好等于 x, 也可能小于 x
- 具体做法如下:
- 初始化左右边界 s 和 e 分别为 0 和 x, 代表查找整个区间
- 初始化最终待求的平方根 res 为 0
- 使用 while 循环保证当前查找范围有效, 即满足 s<=e
- 计算当前两者中点 m, 并比较其平方和 x 的关系
- 如果 m 的平方小于等于 x, 则说明 m 可能是平方根, 将 res 更新为两者的较大值, 然后继续查找右半部分
- 如果 m 的平方大于 x, 则 m 肯定不可能是平方根, 继续查找左半部分
- 最后, 遍历完整个区间后的 res 即为 x 的平方根
- 下面代码中有详细的注释, 方便大家理解
复杂度
- 时间复杂度 O(logx): 需要在区间
[0,x]
之间进行二分查找, 时间复杂度是 O(logx) - 空间复杂度 O(1): 只使用了几个常数空间的变量
代码
class Solution:def mySqrt(self, x: int) -> int:# 二分查找s, e = 0, xres = 0while s <= e:m = (s + e) >> 1if m * m <= x:# 当前m的平方不超过x, 取最大可能的mres = max(res, m)# 然后向右查找s = m + 1else:# 当前m的平方超过了x, 一定不是平方根, 向左查找e = m - 1return res
大家可以在下面这些地方找到我~😊
我的 GitHub
我的 Leetcode
我的 CSDN
我的知乎专栏
我的头条号
我的牛客网博客
我的公众号: 算法精选, 欢迎大家扫码关注~😊
这篇关于Leetcode 剑指 Offer II 072.x 的平方根的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!