RISC-V MCU移植RTOS系列教程(四)
阿新 • • 發佈:2022-03-03
題目連結:
給你一個整數 n
,返回 和為 n
的完全平方數的最少數量 。
完全平方數
示例 1:
輸入:n = 12
輸出:3
解釋:12 = 4 + 4 + 4
示例 2:
輸入:n = 13
輸出:2
解釋:13 = 4 + 9
提示:
-
1 <= n <= 104
解題思路
在這道題中,可以將完全平方數看成是物品(無限個),求裝滿揹包容量為n的最少有多少物品。這就和
運用動態規劃五部曲解決問題:
-
確定dp陣列以及其下標的含義
dp[j]
表示湊成數為j所需的最少完全平方數數量 -
確定遞推公式
dp[j] = min(dp[j], dp[j - i * i]] + 1)
-
dp陣列的初始化
dp[0]
表示 和為0的完全平方數的最小數量,dp[0] = 0
根據遞推公式求最小值,下標非0的
dp[j]
初始化為一個最大的數,否則在比較(dp[j], dp[j - i * i]] + 1)
的過程中被初始值覆蓋掉。 -
確定遍歷順序
本題求解的是完全平方數的最小數量,也就是求數量,與順序沒有關係,所以先遍歷物品還是先遍歷揹包都可以。
-
舉例推導dp陣列(略)
C++
class Solution { public: int numSquares(int n) { vector<int> dp(n + 1, INT_MAX); dp[0] = 0; for (int i = 1; i * i < n; i++) { for (int j = i * i; j < n + 1; j++) { if (dp[j - i * i] != INT_MAX) { dp[j] = min(dp[j], dp[j - i * i] + 1); } } } return dp[n]; } };
JavaScript
/** * @param {number} n * @return {number} */ var numSquares = function(n) { const dp = new Array(n + 1).fill(Number.MAX_VALUE); dp[0] = 0; for (let j = 0; j <= n; j++) { for (let i = 1; i * i <= n; i++) { if (j >= i * i && dp[j - i * i] != Number.MAX_VALUE) { dp[j] = Math.min(dp[j], dp[j - i * i] + 1); } } } return dp[n]; };