完全平方数
给你一个整数 n
,返回 和为 n
的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1
、4
、9
和 16
都是完全平方数,而 3
和 11
不是。
示例 1:
1 2 3
| 输入:n = 12 输出:3 解释:12 = 4 + 4 + 4
|
示例 2:
1 2 3
| 输入:n = 13 输出:2 解释:13 = 4 + 9
|
提示:
问题可以转化为从所有的完全平方数中选择,求出相加恰好等于n
的最少数量,由于每个完全平方数的数量是无限的所以是一个完全背包问题。
f[i][j]
表示从前i
个完全平方数中组成j
的最少数量。
f[i][j]=Math.min(f[i-1][j],f[i][j-i*i])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int numSquares(int n) { int N = 100; int[][] f = new int[101][n + 1]; Arrays.fill(f[0], Integer.MAX_VALUE); f[0][0] = 0; for (int i = 1; i <= 100; i++) { int square = i * i; for (int j = 0; j <= n; j++) { if (square > j) { f[i][j] = f[i - 1][j]; } else { f[i][j] = Math.min(f[i - 1][j], f[i][j - square] + 1); } } } return f[100][n]; } }
|
状态转移时只用到了当前行和上一行的状态所以空间可以优化为1维。
f[i]
表示恰好组成n
的最少数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int numSquares(int n) { int[] f = new int[n + 1]; Arrays.fill(f, Integer.MAX_VALUE); f[0] = 0; for (int i = 1; i <= 100; i++) { int square = i * i; for (int j = square; j <= n; j++) { f[j] = Math.min(f[j], f[j - square] + 1); } } return f[n]; } }
|