当前位置: 首页 > news >正文

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. 搜索范围是 [1, num]

  2. 每次取中点 mid,计算 mid * mid

    • 如果等于 num,那就是完全平方数。
    • 如果比 num 大,说明平方根在左半边。
    • 如果比 num 小,说明平方根在右半边。
  3. 一直缩小范围,直到找到答案。

题解代码分析

下面是 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)

代码拆解

  1. 特殊情况:如果 num < 2,比如 0 或 1,直接返回 true

  2. 二分边界

    • 左边界 left = 1
    • 右边界 right = num / 2,因为平方根不会超过 num/2(除了 num=1)。
  3. 二分逻辑

    • 每次计算 mid * mid
    • 如果等于 num,直接返回 true
    • 如果小于 num,收缩到右区间。
    • 如果大于 num,收缩到左区间。
  4. 返回结果:没找到说明不是完全平方数,返回 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)

空间复杂度

  • 只用了常数级别的变量 leftrightmidsquare
  • 空间复杂度是 O(1)

总结

这道题其实就是把“数学直觉”转化成“计算机算法”的过程:

  • 我们人眼可以轻松判断一个数是不是完全平方数,比如看到 16 就知道是 4²。
  • 但计算机不能直接用 sqrt,就需要用二分查找模拟“开方”的过程。

实际应用场景里,这种“判断平方数”的逻辑可能用在:

  • 图像处理里判断像素矩阵是不是正方形。
  • 数字加密里验证一些平方相关的条件。
  • 游戏开发中做网格计算,判断一个范围是不是可以正好铺满。
http://www.dtcms.com/a/358488.html

相关文章:

  • Notepad++使用技巧1
  • 2025-08-18面试题(nginx,mysql,zabbix为主)
  • C#正则表达式与用法
  • unity学习——视觉小说开发(二)
  • JsMind 常用配置项
  • Qt中的锁(1)
  • AFSIM仿真工具介绍与源码编译
  • Isaac Lab Newton 人形机器人强化学习 Sim2Real 训练与部署
  • uniapp监听物理返回按钮事件
  • 软考 系统架构设计师系列知识点之杂项集萃(136)
  • 将 Logits 得分转换为概率,如何计算
  • SRE命令行兵器谱之三:grep - 日志海洋中的“精确制导”
  • JavaWeb前端06(ElementPlus快速构建网页)
  • IDM手机端,速度能提高6倍!
  • 消息队列核心技术解析与应用场景
  • JAVA EE初阶 4:文件操作和IO
  • 使用 SVM(支持向量机)进行图像分类:从读取图像到训练与分类的完整流程
  • Python API接口实战指南:从入门到精通
  • HarmonyOS三方库的使用
  • Java SpringAI应用开发面试全流程解析:RAG、流式推理与企业落地
  • 【Java工程师面试全攻略】Day13:云原生架构与Service Mesh深度解析
  • 防火墙技术(二):安全区域
  • 【Linux】系统部分——软硬链接动静态库的使用
  • Tomcat 企业级运维实战系列(四):Tomcat 企业级监控
  • 每日Java并发面试系列(5):基础篇(线程池的核心原理是什么、线程池大小设置为多少更合适、线程池哪几种类型?ThreadLocal为什么会导致内存泄漏?)
  • Tomcat 企业级运维实战系列(三):Tomcat 配置解析与集群化部署
  • Qt实战:如何打开摄像头并实现视频的实时预览
  • 生成式 AI 重构内容生产:效率提升背后的创作版权边界争议
  • react虚拟列表实现及原理
  • leetcode2(移除元素)