LeetCode 279. 完全平方数
给你一个整数
n
,返回 和为n
的完全平方数的最少数量 。完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,
1
、4
、9
和16
都是完全平方数,而3
和11
不是。示例 1:
输入:n = 12 输出:3 解释:12 = 4 + 4 + 4示例 2:
输入:n = 13 输出:2 解释:13 = 4 + 9提示:
1 <= n <= 104
思路:
时间复杂度:
O(n√n),其中 n 为给定的正整数。状态转移方程的时间复杂度为 O(√n),共需要计算 n 个状态,因此总时间复杂度为 O(n√n)。
空间复杂度:
O(n)。我们需要 O(n) 的空间保存状态。
// 理解:找到n之前最大的一个完全平方数j(j*j<=n),记为一个个数;那么 还剩n-j*j需要继续拼凑。也就是说只要将n-j*j的解dp[n-j*j] 加上上面j*j所占的那个1,就是n的解,这就是最短的。func numSquares(n int) int {dp := make([]int, n+1)dp[0] = 0 // 题目要求从1的平方开始,所以0的情况可忽略for i := 1; i <= n; i++ {dp[i] = n+1 // dp[i]一开始全部都初始化为了n+1,比要求的n还大}for i := 1; i <= n; i++ { // 当前循环中,需要组合的完全平方数为nfor j := 1; j*j <= i; j++ {// j从1开始,j*j不断增大,因此 diff=i-j*j 最终可以保证差值最小// +1:且j*j本身也是组成目标和n的其中一个完全平方数。// 比如:dp[13]=min(dp[13], dp[13-1*1]), dp[13]=min(dp[13], dp[13-2*2]), dp[13]=min(dp[13], dp[13-3*3])...dp[i] = min(dp[i], dp[i-j*j] + 1) }}return dp[n]
}func min(a, b int) int {if a < b {return a}return b
}