20210611 每日一题 完全平方数

题目

题目链接

代码

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

    }
};

方法一:BFS

分析

这题让求的是若干个平方数的和等于n,并且平方数的个数最少。首先我们可以将题目想象成为一颗根节点为 n n n 的多叉树,树的每子节点、叶子节点的值都是小于父节点数值的平方数 y ( y 2 ≤ n ) y(y^2 \leq n) y(y2n) 的平方和,用BFS广度优先搜索寻找 y 2 = n y^2 = n y2=n 的结点,此时的树深度 d e p t h depth depth 即为 n n n 的完全平方数的最小数量。

代码

class Solution {
public:
    int numSquares(int n) {
        unordered_set<int> visited;
        queue<int> Q;
        int ans = 1;
        Q.push(n);
        while(Q.size()) {
            int cur = Q.size();
            while(cur--) {
                int x = Q.front();
                Q.pop();
                for(int y = (int)sqrt(x); y > 0; y--) {
                    int t = x - y * y;
                    if(t == 0) return ans;
                    if(!visited.count(t)) {
                        visited.insert(t);
                        Q.push(t);
                    }
                }
            }
            ans++;
        }
        return 0;
    }
};

复杂度分析

  • 时间复杂度: O ( V + E ) O(V+E) O(V+E),其中 V V V 是多叉树中节点的数量, E E E 是多叉树中边的数量。
  • 空间复杂度: O ( V ) O(V) O(V),其中 V V V 是多叉树中节点的数量,实现BFS需要最多需要 V V V 的队列 Q Q Q

方法二:一维动态规划

分析

该题目是一道典型的完全背包,设定一维数组 d p [ i ] dp[i] dp[i] 表示构成 i i i 的完全平方数的最少数量,当 i = 0 i = 0 i=0 时,只有一种情况,即 d p [ 0 ] = 0 dp[0] = 0 dp[0]=0,因为本题目是找最小值,因此其余初始值为 I N T _ M A X INT\_MAX INT_MAX。我们可以先使用数字 j   ( j 2 ≤ i ) j \ (j^2 \leq i) j (j2i) 来依次遍历所有解,状态转移方程可表示为:
d p [ i ] = m i n ( d p [ i − j 2 ] + 1 ,   d p [ i ] ) dp[i] = min(dp[i - j^2] + 1, \ dp[i]) dp[i]=min(dp[ij2]+1, dp[i]) 问题答案为:
d p [ n ] dp[n] dp[n]

代码

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp (n + 1, INT_MAX);
        dp[0] = 0;
        for(int i = 0; i <= n; i++) { // 遍历背包
            for(int j = 1; j * j <= i; j++) { // 遍历物品
                dp[i] = min(dp[i - j * j] + 1, dp[i]);
            }
        }
        return dp[n];
    }
};

复杂度分析

  • 时间复杂度: O ( n n ) O(n \sqrt{n}) O(nn ),其中 n n n 是给定数值, n \sqrt{n} n j j j 的循环次数。
  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是给定数值,实现动态规划需要创建 n n n 的一维数组 d p dp dp

拓展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值