Leetcode 279. 完全平方数

Leetcode 279. 完全平方数

1、问题分析

题目链接:https://leetcode-cn.com/problems/perfect-squares/
  本质上就是一个动态规划问题。代码我已经进行了详细的注释,理解应该没有问题,读者可以作为参考,如果看不懂(可以多看几遍),欢迎留言哦!我看到会解答一下。

2、问题解决

  笔者以C++方式解决。

#include "iostream"

using namespace std;

#include "algorithm"
#include "vector"
#include "queue"
#include "set"
#include "map"
#include "string"
#include "stack"

class Solution {
    // 定义 i 最少可以用多少个完全平方数表示,即个数数组
    // 例如: dp[10] 代表 10 最少可以用多少个完全平方数表示
    vector<int> dp;
    // 定义完全平方数数组,存储 i*i<=n 的所有数
    // 例如 n == 10, square={1,2,3}
    vector<int> square;
public:
    int numSquares(int n) {
        // 边界处理
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        // 初始化个数数组
        dp.resize(n);

        // 初始化完全平方数数组
        for (int i = 1; i < n; ++i) {
            if (i * i <= n) {
                square.push_back(i);
            }
            else {
                break;
            }
        }

        return dealChen(n);
    }

    /**
     * 计算 n 最少可以由多少个完全平方数组成
     * @param n
     * @return
     */
    int dealChen(int n) {

        // 递归边界,这里仍然要注意不要溢出
        if (n < 0) {
            return INT_MAX / 100;
        }

        // 0 说明不需要完全平方数,直接返回 0
        if (n == 0) {
            return 0;
        }

        // 如果值已经计算过,则直接返回
        if (dp[n-1] != 0) {
            return dp[n-1];
        }

        int number_chen = INT_MAX/2;
        // 遍历完全平方数数组
        // 状态转移方程为 :
        // dp[n] = dp[n-i*i] + 1
        for (int i = square.size() - 1; i >= 0; --i) {
            // 选择其中最小的一个
            number_chen = min(number_chen, dealChen(n - square[i] * square[i]) + 1);
        }
        // 存储 最少可以由多少个完全平方数组成
        dp[n-1] = number_chen;
        // 返回计算结果
        return dp[n-1];
    }
};

int main() {

    Solution *pSolution = new Solution;
    int i = pSolution->numSquares(13);
    cout << i << endl;
    system("pause");
    return 0;
}

运行结果

在这里插入图片描述

有点菜,有时间再优化一下。

3、总结

  难得有时间刷一波LeetCode, 这次做一个系统的记录,等以后复习的时候可以有章可循,同时也期待各位读者给出的建议。算法真的是一个照妖镜,原来感觉自己也还行吧,但是算法分分钟教你做人。前人栽树,后人乘凉。在学习算法的过程中,看了前辈的成果,受益匪浅。
感谢各位前辈的辛勤付出,让我们少走了很多的弯路!
哪怕只有一个人从我的博客受益,我也知足了。
点个赞再走呗!欢迎留言哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章