有效的完全平方数
LeetCode 367:用二分查找判断是否存在平方恰好等于 num 的整数。
给你一个正整数 num。如果 num 是一个 完全平方数,则返回 true,否则返回 false。
完全平方数是可以写成某个整数与自身乘积的整数,例如 16 = 4 * 4。
注意: 不能使用任何内置的库函数,如 sqrt。
示例 1:
- 输入:
num = 16 - 输出:
true - 解释:
4 * 4 = 16,且4是整数。
示例 2:
- 输入:
num = 14 - 输出:
false - 解释:
3 * 3 = 9 < 14 < 16 = 4 * 4,没有整数的平方恰好等于14。
1. 查找过程
要找的是 平方恰好等于 num 的整数。非负整数越大,平方越大,可以用二分查找缩小范围。
下面是区间示意:k 表示候选整数,k² 表示它的平方;L、M、R 对应代码中的 l、mid、r。
1.1 找到整数平方根:num = 16
第 1 轮:检查 [0, 15]
| |
mid = 7,7 * 7 = 49 > 16。7 已经太大,右侧的数也都太大。
更新 r = mid - 1,得到 r = 6,剩下 [0, 6]。
第 2 轮:检查 [0, 6]
| |
mid = 3,3 * 3 = 9 < 16。3 太小,左侧的数也都太小。
更新 l = mid + 1,得到 l = 4,剩下 [4, 6]。
第 3 轮:检查 [4, 6]
| |
mid = 5,5 * 5 = 25 > 16,排除 5 和 6。
更新 r = mid - 1,得到 r = 4,只剩 4。
第 4 轮:只检查整数 4
| |
mid = 4,4 * 4 == 16,找到满足条件的整数,直接返回 True。
1.2 没有整数平方根:num = 14
同样从 [0, num - 1] 开始,逐轮变化如下:
本轮区间 [l, r] | mid | 平方比较 | 更新边界 |
|---|---|---|---|
[0, 13] | 6 | 36 > 14 | r = 5 |
[0, 5] | 2 | 4 < 14 | l = 3 |
[3, 5] | 4 | 16 > 14 | r = 3 |
[3, 3] | 3 | 9 < 14 | l = 4 |
最后 l = 4 > r = 3,区间已空。所有可能值都被排除,没有一次平方恰好等于 14,返回 False。
2. Python 实现
当 num >= 2 时,若存在整数平方根,它一定小于 num,所以右边界可以取 num - 1。
| |
| |
3. 复杂度
- 时间复杂度:
O(log num),每轮将整数候选区间缩小约一半。 - 额外空间复杂度:
O(1),只维护固定数量的整数变量。
评论
使用 GitHub 登录后参与讨论,评论将公开保存在 GitHub。
站长管理删除会同步到 GitHub,无法撤销。
阅读到这里时加载评论。