279. 完全平方数 - 力扣(LeetCode)
这道题目最好的解放时用动态规划的思想去做,这需要在推到的过程中想到如下表达式
其实去求每个数值的解的时候,都是通过把 i 下所有可能的取值中选出最小值加1。
通过上述表达式,可以从i为0开始一步步求解,最后得到f
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1);
for(int i=1;i<=n;++i)
{
int min_val=INT_MAX;
for(int j=1;j*j<=i;++j)
{
min_val=min(min_val,dp[i-j*j]);
}
dp[i]=min_val+1;
}
return dp[n];
}
};
一开始没有想到动态规划的思想,通过下面的递归思想去做的,但是结果不如动态规划的好。递归的过程中要想着将递归中的值回收使用,还有就是一个减去分支有的时候也要注意。
class Solution {
public:
/*利用迭代的思路,每次都去找[sqrt(n)],然后再去算n-num*num的结果,比较所有的结果,通过一个哈希map来存 放之前已经求出数值的每个结果,这样可以方便后面迭代的过程中去直接使用,不用再计算一次,节省了时间*/
unordered_map<int,int> check;
int numSquares(int n) {
if(n==0)return 0;
if(check.find(n)!=check.end())return check[n];
int num=sqrt(n),ans=INT_MAX;
if(num*num==n)return 1;//说明n是一个可以被完全二次开放的一个整数
for(;num>=1;--num)
{
int temp=0;
if(check.find(n-num*num)!=check.end())temp=check[n-num*num]+1;
else temp=numSquares(n-num*num)+1;
if(temp<=ans)ans=temp;//终止条件也是一个问题,还是应该要在temp比ans大的时候才结束查找
}
if(check.find(n)==check.end())check[n]=ans;
return ans;
}
};