方法一:(动态规划)
class Solution {
public int numSquares(int n) {
int[] dp=new int[n+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0]=0;
int max_square_index=(int)Math.sqrt(n)+1;
int[] square_nums=new int[max_square_index];
for(int i=1;i<max_square_index;i++) {
square_nums[i]=i*i;
}
for(int i=1;i<=n;i++) {
for(int s=1;s<max_square_index;s++) {
if(i<square_nums[s]) {
break;
}
dp[i]=Math.min(dp[i],dp[i-square_nums[s]]+1);
}
}
return dp[n];
}
}
方法二:(贪心做法)
class Solution {
public static boolean is_Divided_by(int n,int count,HashSet<Integer> square_nums) {
if(count==1) {
return square_nums.contains(n);
}
for(Integer square : square_nums) {
if(is_Divided_by(n-square, count-1, square_nums)) {
return true;
}
}
return false;
}
public int numSquares(int n) {
HashSet<Integer> square_nums=new HashSet<Integer>();
for(int i=1;i*i<=n;i++) {
square_nums.add(i*i);
}
int count=1;
for(;count<=n;count++) {
if(is_Divided_by(n, count,square_nums)) {
return count;
}
}
return count;
}
}
方法三:(BFS)
class Solution {
public int numSquares(int n) {
List<Integer> square_nums=new ArrayList<Integer>();
for(int i=1;i*i<=n;i++) {
square_nums.add(i*i);
}
Set<Integer> queue=new HashSet<Integer>();
queue.add(n);
int level=0;
while(queue.size()>0) {
level+=1;
Set<Integer> new_queue=new HashSet<Integer>();
for(Integer reminder : queue) {
for(Integer square : square_nums) {
if(reminder.equals(square)) {
return level;
}else if(reminder<square) {
break;
}else {
new_queue.add(reminder-square);
}
}
}
queue=new_queue;
}
return level;
}
}