LeetCode279

题目:
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9

其实这个题的难点在于如何将题目转化为数学模型,说实话,没动笔之前还真的是想不到
一个数,它可以有多种不同的完全平方数和,该题需要的就是最少的完全平方数
因为组成它的每个数都需要是完全平方数,那么可以先找到比它小的所有完全平方数,该数分别减去这些完全平方数,得到下一个n,同样的方法操作这个n
那么就可以看做是,一个根,它的孩子是它与小于它的平方数的差,对于每个差值同样作为根去重复操作
这样以来,每一层,就是找到一个完全平方数之后的差,那么当差值为0的时候,就说明找到底了,第一次出现差值为0的层,就是最少的个数
这样的话就可以使用bfs遍历每一层,而不能使用dfs深度遍历,
因为深度遍历的话,还需要保存深度值和其他比较,且并不知道哪个子树是最深的,这样的话逮着一个不确定的子树一直遍历太消耗时间了


	public int numSquares(int n) {
    
    
		ArrayList<Integer> square_numbers=new ArrayList<>();
	       for(int i=1;i*i<=n;i++) {
    
    
	       	square_numbers.add(i*i);
	       }
	       ArrayDeque<Integer> queue=new ArrayDeque<>();
	       queue.add(n);
	       int level=0;
	       while(!queue.isEmpty()) {
    
    
	       	level++;
	       	int size=queue.size();
	       	for(int i=0;i<size;i++) {
    
    
	       		for(int j:square_numbers) {
    
    
	                   if(queue.getFirst()<j)break;
	       			if(queue.getFirst()==j) {
    
    
	       				return level;
	       			}
	                   queue.add(queue.getFirst()-j);
	       		}
	               queue.pollFirst(); 
	               
	       	}
	       			
	       }
	       return level;
	       
	   }

在这里插入图片描述
放个图看的清楚些了

猜你喜欢

转载自blog.csdn.net/qq_50646256/article/details/113856374
今日推荐