个人技术分享

1. 题目

2. 解题思路

此图利用动态规划进行求解,首先,我们求出小于 n n n 的所有完全平方数,存放在数组 squareNums 中。

定义 dp[n] 为和为 n n n 的完全平方数的最小数量,那么有状态转移方程:

d p [ n ] = m i n ( d p [ n − s q u a r e N u m s [ i ] ] + 1 , d p [ n ] ) , 对于任意  s q u a r e N u m s [ i ] < n dp[n] = min(dp[n-squareNums[i]] + 1, dp[n]), 对于任意 \space squareNums[i] < n dp[n]=min(dp[nsquareNums[i]]+1,dp[n]),对于任意 squareNums[i]<n
d p [ n ] = 1 ,对于  s q u a r e N u m s [ i ] = = n dp[n] = 1,对于 \space squareNums[i] == n dp[n]=1,对于 squareNums[i]==n

3. 代码实现

class Solution {
public:
    int numSquares(int n) {

        vector<int> squareNums;
        for (int i = 1; i < n; ++i) {
            if (i * i > n) {
                break;
            }
            squareNums.push_back(i * i);
        }
        vector<int> dp(n+1, 10000);
        dp[1] = 1;
        for (int i = 2; i <= n; ++i) {
            for (int j = 0; j < squareNums.size(); ++j) {
                if (squareNums[j] > i) {
                    break;
                } else if (squareNums[j] == i) {
                    dp[i] = 1;
                } else {
                    dp[i] = min(dp[i], dp[i - squareNums[j]] + 1);
                } 
            }
        }
        return dp[n];
    }
};

时间复杂度为 O ( n n ) O(n\sqrt{n}) O(nn ),第一层循环 n n n 次,第二层循环 n \sqrt{n} n 次,空间复杂度为 O ( n ) O(n) O(n),其中 squareNums 占用空间为 O ( n ) O(\sqrt{n}) O(n ),也可以省略,直接在第二个循环得到 j ∗ j j*j jjdp 占用空间为 O ( n ) O(n) O(n)