Swift 解法详解:LeetCode 367《有效的完全平方数》
文章目录
- 摘要
- 描述
- 题解答案
- 题解代码分析
- 代码拆解
- 示例测试及结果
- 时间复杂度
- 空间复杂度
- 总结
摘要
判断一个数是不是完全平方数,看似简单,但题目要求我们不能用 sqrt
这样的现成函数。也就是说,我们得自己想办法去模拟“开平方”的过程。这种题很有意思,不光能训练我们对二分查找的掌握,还能让我们思考数字在计算机里的表现方式。
描述
题目给了一个正整数 num
,问它是不是某个整数的平方。
- 如果是,返回
true
。 - 如果不是,返回
false
。
完全平方数:就是能写成 a * a
形式的数,比如:
- 16 = 4 * 4
- 9 = 3 * 3
- 25 = 5 * 5
但像 14 就不行,它介于 3² 和 4² 之间,平方根不是整数。
输入输出例子:
输入:num = 16
输出:true输入:num = 14
输出:false
题解答案
一个直接的办法是从 1 开始,一个个平方,看是不是等于 num
。但这样效率太低,尤其是 num
最大能到 2^31 - 1
(20 多亿)。
更高效的方式是用 二分查找:
-
搜索范围是
[1, num]
。 -
每次取中点
mid
,计算mid * mid
:- 如果等于
num
,那就是完全平方数。 - 如果比
num
大,说明平方根在左半边。 - 如果比
num
小,说明平方根在右半边。
- 如果等于
-
一直缩小范围,直到找到答案。
题解代码分析
下面是 Swift 的实现:
import Foundationclass Solution {func isPerfectSquare(_ num: Int) -> Bool {if num < 2 {return true}var left = 1var right = num / 2 // 平方根不可能超过 num/2 (除非 num=1)while left <= right {let mid = left + (right - left) / 2let square = mid * midif square == num {return true} else if square < num {left = mid + 1} else {right = mid - 1}}return false}
}// MARK: - Demo 演示
let solution = Solution()
print(solution.isPerfectSquare(16)) // true
print(solution.isPerfectSquare(14)) // false
print(solution.isPerfectSquare(1)) // true
print(solution.isPerfectSquare(808201)) // true (因为 899 * 899 = 808201)
代码拆解
-
特殊情况:如果
num < 2
,比如 0 或 1,直接返回true
。 -
二分边界:
- 左边界
left = 1
。 - 右边界
right = num / 2
,因为平方根不会超过num/2
(除了num=1
)。
- 左边界
-
二分逻辑:
- 每次计算
mid * mid
。 - 如果等于
num
,直接返回true
。 - 如果小于
num
,收缩到右区间。 - 如果大于
num
,收缩到左区间。
- 每次计算
-
返回结果:没找到说明不是完全平方数,返回
false
。
示例测试及结果
运行上面 Demo,得到结果:
true
false
true
true
更丰富的测试:
print(solution.isPerfectSquare(25)) // true
print(solution.isPerfectSquare(26)) // false
print(solution.isPerfectSquare(100)) // true
print(solution.isPerfectSquare(2147395600)) // true (46340 * 46340)
print(solution.isPerfectSquare(2147483647)) // false (最大 int,不是平方数)
时间复杂度
- 二分查找每次把搜索区间减半,最多执行 O(log n) 次比较。
- 每次计算
mid * mid
是 O(1)。 - 所以整体复杂度是 O(log n)。
空间复杂度
- 只用了常数级别的变量
left
、right
、mid
、square
。 - 空间复杂度是 O(1)。
总结
这道题其实就是把“数学直觉”转化成“计算机算法”的过程:
- 我们人眼可以轻松判断一个数是不是完全平方数,比如看到 16 就知道是 4²。
- 但计算机不能直接用
sqrt
,就需要用二分查找模拟“开方”的过程。
实际应用场景里,这种“判断平方数”的逻辑可能用在:
- 图像处理里判断像素矩阵是不是正方形。
- 数字加密里验证一些平方相关的条件。
- 游戏开发中做网格计算,判断一个范围是不是可以正好铺满。