279. 完全平方数

279. 完全平方数

1.题目描述

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
在这里插入图片描述
示例 2:
在这里插入图片描述

2.思路(动态规划)

假设最小完全平方的个数ƒ(n)=mƒ(n) = mƒ(n)=m,那么nnn的值满足下列公式 ∑(A[i]∗A[i])=n∑(A[i] * A[i]) = n(A[i]A[i])=n
kkk 为满足最小值 mmm 的时候,最大的平方数 。 令 d+k∗k=n;d>=0d + k*k = n ; d >= 0d+kk=n;d>=0。( 注意:一定要是满足m最小的时候的kkk值)
得出 f(d)+f(k∗k)=f(n)f(d) + f(k*k) = f(n)f(d)+f(kk)=f(n) 显然f(k∗k)=1f(k * k) = 1f(kk)=1; 则 f(d)+1=f(n)f(d) + 1 = f(n)f(d)+1=f(n); 因为d=n−k∗kd = n - k*kd=nkk
则可以推出ƒ(n−k∗k)+1=ƒ(n)ƒ(n - k * k) + 1 = ƒ(n)ƒ(nkk)+1=ƒ(n) ; 且 k∗k<=nk * k <= nkk<=n,所以动态转移方程:
dp[i]=min(dp[i],dp[i−j∗j]+1)dp[i] = min(dp[i], dp[i - j * j] + 1)dp[i]=min(dp[i],dp[ijj]+1)

3.代码

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1);
        for(int i = 1;i <= n;++i){
            dp[i] = i;//最多的情况是分解为全1
            for(int j = 1; i - j*j >= 0;++j){
                dp[i] = min(dp[i],dp[i-j*j]+1);
            }
        }
        return dp[n];
    }
};

4.复杂度分析

时间复杂度:O(n*sqrt(n)),sqrt为平方根
空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值