279. 完全平方数
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/perfect-squares
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:BFS广度优先搜索,从小到大搜索
class Solution {
public int numSquares(int n) {
Set<Integer> visited=new HashSet<>();//存放已经加出来过的数值
Queue<Integer> q=new LinkedList<>();
q.offer(0);
visited.add(0);
int count=0;
while(!q.isEmpty())//队列不空
{
count++;//每一层步数加一
int size=q.size();//如果直接写成for(int i=0;i<q.size();i++)会出错,我也不知道为什么。。
for(int i=0;i<size;i++)
{
int cur=q.poll();
for(int j=1;j*j+cur<=n;j++)
{
int sum=cur+j*j;
if(sum==n)//如果sum等于n,当前计数即为最后结果
{
return count;
}
if(sum<n&&!visited.contains(sum))//否则比较数组中是否有当前值
{
//没有的话就把当前值加入队列和数组中
q.offer(sum);
visited.add(sum);
}
}
}
}
return count;
}
}
方法二:BFS广度优先搜索,但从大到小搜索
class Solution {
public int numSquares(int n) {
Queue<Integer> q=new LinkedList<>();//存放剩余值
q.offer(n);//刚开始为n
int count=0;
while(!q.isEmpty())
{
count++;
int size=q.size();
for(int i=0;i<size;i++)
{
int cur=q.poll().intValue();
int maxSqrt=(int)Math.sqrt(cur);//求出n的最大平方根
if(maxSqrt*maxSqrt==cur)
{
return count;
}
for(int j=maxSqrt;j>0;j--)//从大到小试
{
q.offer(cur-j*j);//记录剩余值
}
}
}
return count;
}
}
知识点:
- public abstract int intValue()返回指定数字的值为 int ,可能涉及四舍五入或截断。
结果:该对象在转换为 int之后表示的 int 。
方法三*:动态规划,动态转移方程没看太懂,不知道怎么来的
class Solution {
public int numSquares(int n) {
int[] dp = new int[n + 1]; // 默认初始化值都为0
for (int i = 1; i <= n; i++) {
dp[i] = i; // 最坏的情况就是每次+1
for (int j = 1; i - j * j >= 0; j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1); // 动态转移方程
}
}
return dp[n];
}
}