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
, 這次做一個系統的記錄,等以後複習的時候可以有章可循,同時也期待各位讀者給出的建議。算法真的是一個照妖鏡,原來感覺自己也還行吧,但是算法分分鐘教你做人。前人栽樹,後人乘涼。在學習算法的過程中,看了前輩的成果,受益匪淺。
感謝各位前輩的辛勤付出,讓我們少走了很多的彎路!
哪怕只有一個人從我的博客受益,我也知足了。
點個贊再走唄!歡迎留言哦!