Swift 数据结构与算法( 12) 数组 + S_Leetcode69. x 的平方根 (二分)

128 阅读2分钟

Swift 数据结构与算法( ) 数组 + Leetcode

概念

题目

69. x 的平方根

给你一个非负整数 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 {

  1. 理解它的含义left <= right 在每次循环中都会检查。当 left > right 时,循环将停止。这意味着搜索空间为空,我们已经找不到目标值了。这是一个自然的结束点。
  2. 记住模板:二分查找有一些标准模板,其中最常见的就是 while (left <= right)。如果可以记住这个模板,就可以避免在边界条件上出错。
  3. 理解更新规则:在二分查找中,我们会根据中间值和目标值的比较结果来更新左右边界。当中间值``小于目标值时,我们会更新左边界为 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)

截屏2023-08-03 23.42.35.png

引用