1. 程式人生 > 其它 >RISC-V MCU移植RTOS系列教程(四)

RISC-V MCU移植RTOS系列教程(四)

279. 完全平方數

題目連結: 279. 完全平方數(中等)

給你一個整數 n ,返回 和為 n 的完全平方數的最少數量

完全平方數 是一個整數,其值等於另一個整數的平方;換句話說,其值等於一個整數自乘的積。例如,14916 都是完全平方數,而 311 不是。

示例 1:

輸入:n = 12
輸出:3
解釋:12 = 4 + 4 + 4

示例 2:

輸入:n = 13
輸出:2
解釋:13 = 4 + 9

提示:

  • 1 <= n <= 104

解題思路

在這道題中,可以將完全平方數看成是物品(無限個),求裝滿揹包容量為n的最少有多少物品。這就和322. 零錢兌換

一模一樣的解法了。

運用動態規劃五部曲解決問題:

  1. 確定dp陣列以及其下標的含義

    dp[j]表示湊成數為j所需的最少完全平方數數量

  2. 確定遞推公式

    dp[j] = min(dp[j], dp[j - i * i]] + 1)

  3. dp陣列的初始化

    dp[0]表示 和為0的完全平方數的最小數量,dp[0] = 0

    根據遞推公式求最小值,下標非0的dp[j]初始化為一個最大的數,否則在比較(dp[j], dp[j - i * i]] + 1)的過程中被初始值覆蓋掉。

  4. 確定遍歷順序

    本題求解的是完全平方數的最小數量,也就是求數量,與順序沒有關係,所以先遍歷物品還是先遍歷揹包都可以。

  5. 舉例推導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];
};