279. 完全平方数
题目:
思路:
【1】动态规划的方式
【2】数学公式的方式(依据 四平方和定理 )
同时四平方和定理包含了一个更强的结论:
当且仅当 n≠4^k×(8m+7) 时,n 可以被表示为至多三个正整数的平方和。
因此,当 n=4^k×(8m+7) 时,n 只能被表示为四个正整数的平方和。此时我们可以直接返回 4。
当 n≠4^k×(8m+7) 时,我们需要判断到底多少个完全平方数能够表示 n,我们知道答案只会是 1,2,3 中的一个:
答案为 1 时,则必有 n 为完全平方数,这很好判断;
答案为 2 时,则有 n=a^2+b^2,我们只需要枚举所有的 a(1≤a≤√n),判断 n-a^2 是否为完全平方数即可;
答案为 3 时,我们很难在一个优秀的时间复杂度内解决它,故只需要检查答案为 1 或 2 的两种情况,即可利用排除法确定答案。
代码展示:
【1】动态规划的方式
//时间21 ms 击败 91.34% //内存40.2 MB 击败 86.21% //时间复杂度:O(n * √n),其中 n 为给定的正整数。 //状态转移方程的时间复杂度为 O(√n)[n的平方根],共需要计算 n 个状态, //因此总时间复杂度为 O(n * √n)。 //空间复杂度:O(n)。我们需要 O(n) 的空间保存状态。 class Solution { public int numSquares(int n) { // 动态规划的方式列出从 1 - n 完全平方数的最少数量 int[] f = new int[n+1]; for (int i = 1; i <= n; i++){ int minn = Integer.MAX_VALUE; for (int j = 1; j * j <= i; j++) { minn = Math.min(minn, f[i - j * j]); } f[i] = minn + 1; } return f[n]; } }
【2】数学公式的方式
//时间0 ms 击败 100% //内存38.1 MB 击败 99.90% class Solution { public int numSquares(int n) { if (isPerfectSquare(n)) { return 1; } if (checkAnswer4(n)) { return 4; } for (int i = 1; i * i <= n; i++) { int j = n - i * i; if (isPerfectSquare(j)) { return 2; } } return 3; } // 判断是否为完全平方数 public boolean isPerfectSquare(int x) { int y = (int) Math.sqrt(x); return y * y == x; } // 判断是否能表示为 4^k*(8m+7) public boolean checkAnswer4(int x) { while (x % 4 == 0) { x /= 4; } return x % 8 == 7; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现