Swift 数据结构与算法( ) 数组 + Leetcode
概念
题目
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意: 不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入: x = 4
输出: 2
示例 2:
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
class Solution {
func mySqrt(_ x: Int) -> Int {
}
}
解题思路🙋🏻 ♀️
需要搞清楚条件是什么?
这一题的条件是比较 平方根, 所以比较的是 Mid 的平方
结果一定在 0 和 x 之间,所以我们将左边界 L 设置为 0,右边界 R 设置为 x。然后,我们取 L 和 R 的中间值 M,判断 M 的 2 次方 与 x 的大小关系。
错误分析
本题我自己犯错了, 我一开始返回的是 left. 实际上应该是 right
对于像 x=8 这样的输入,不存在一个整数的平方等于 8,所以函数会跳过这个等号判断。当 left>right 时,我返回了 left。但是,在这个问题中,当结束循环时,left 一定是大于真正的答案的,所以我应该返回 right, 才是安全的值...
反思:
没有精准记得这个跳出循环的 left 已经大于 right 了
while left <= right {
- 理解它的含义:
left <= right在每次循环中都会检查。当left > right时,循环将停止。这意味着搜索空间为空,我们已经找不到目标值了。这是一个自然的结束点。 - 记住模板:二分查找有一些标准模板,其中最常见的就是
while (left <= right)。如果可以记住这个模板,就可以避免在边界条件上出错。 - 理解更新规则:在二分查找中,我们会根据中间值和目标值的比较结果来更新左右边界。当
中间值``小于目标值时,我们会更新左边界为mid + 1,因为我们知道目标值不可能在左半部分。当中间值``大于目标值时,我们会更新右边界为mid - 1,因为我们知道目标值不可能在右半部分。记住这些规则可以帮助理解为什么我们要在left > right时停止循环。
边界思考🤔
代码
class Solution {
func mySqrt(_ x: Int) -> Int {
var left = 0
var right = x
while left <= right {
let mid = left + (right - left) / 2
if mid * mid <= x {
left = mid + 1
} else {
right = mid - 1
}
}
return right
}
}
时空复杂度分析
O (logn)