• 343. 整数拆分


    343. 整数拆分

    题目链接:343. 整数拆分(中等)

    给定一个正整数 n ,将其拆分为 k正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

    返回 你可以获得的最大乘积

    示例 1:

    输入: n = 2
    输出: 1
    解释: 2 = 1 + 1, 1 × 1 = 1。

    示例 2:

    输入: n = 10
    输出: 36
    解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

    提示:

    • 2 <= n <= 58

    解题思路

    方法一:动态规划

    1. 确定dp数组以及其下标的含义

      dp[i]表示拆分数字i,可以得到的最大乘积为dp[i]

    2. 确定递推公式

      题目中给定的n是不小于2的,这里的n也就是dp数组中的i,假设对正整数i拆分出的第一个正整数是j,这里的j满足1 <= j < i,可以有两种方式:

      • 整数i只拆分为两个数的和。也就是将i拆分成j(i-j)的和、且(i-j)不再继续拆分为其他整数的和,此时的乘积是 j × (i-j) ;

      • 整数i拆分为多个整数的和,一定是大于2个的。也就是将i拆分成j(i-j)的和、且(i-j)继续拆分为多个正整数相加(也就是整数(i-j)的最大乘积),此时的乘积是j × dp[i-j]

      于是可得递推公式为dp[i] =max(dp[i],max(j × (i-j), j × dp[i-j]))

    3. dp数组的初始化

      dp[2] = 1(拆分从2开始的,0和1不能拆分)

    4. 确定遍历顺序

      dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2]正好可以通过我们初始化的数值求出来。

    5. 举例推导dp数组

      n = 10时,dp数组如下

       

    C++

    class Solution {
    public:
        int integerBreak(int n) {
            //1. dp[i]表示拆分数字i,可以得到的最大乘积为dp[i]
            vector<int> dp(n + 1);
            //3. 初始化dp数组
            dp[2] = 1;
            //4. 遍历顺序
            for (int i = 3; i <= n; i++) {
                for (int j = 1; j <= i / 2; j++) {
                    //2. 状态方程
                    dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
                }
            }
            return dp[n];
        }
    };

    JavaScript

    /**
     * @param {number} n
     * @return {number}
     */
    var integerBreak = function(n) {
        const dp = new Array(n + 1).fill(0);
        dp[2] = 1;
        for (let i = 3; i <= n; i++) {
            for (let j = 1; j <= i / 2; j++) {
                dp[i] = Math.max(dp[i], Math.max((i - j) * j), dp[i - j] * j);
            }
        }
        return dp[n];
    };

    时间复杂度:O(n^2)

    空间复杂度:O(n)

    方法二:贪心算法

    本题也可以用贪心,每次拆成n个3,如果剩下是4,则保留4,然后相乘。

    C++

    class Solution1 {
    public:
        int integerBreak(int n) {
            int result = 1;
            if (n == 2) return 1;
            if (n == 3) return 2;
            if (n == 4) return 4;
            while (n > 4) {
               result = result * 3;
               n = n - 3;
            }
            result = result * n;
            return result;
        }
    };

     

  • 相关阅读:
    asp.net中的Application概述
    Android布局
    Content Provider
    Service
    进程和线程Processes and Threads
    Android模拟器
    Fragment
    Ui Event
    Loader
    sqlite3命令
  • 原文地址:https://www.cnblogs.com/wltree/p/15948887.html
Copyright © 2020-2023  润新知