力扣刷题笔记【动态规划】 → 343. 整数拆分

230 阅读1分钟

这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

题目

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

说明: 你可以假设 n 不小于 2 且不大于 58。

示例

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

解题思路

动态规划

n >= 2时,我们至少可以将其拆分成两个正整数,假设i为拆分出当第一个正整数,则剩下当部分为n - in - i分为如下两种情况:

  • 不可继续拆分成为多个正整数,则此时当乘积为i * (n - i)
  • 可以继续拆分,那么我们则需要使用到前面得到的结果,此时乘积为i * dp[n - i]

在该基础上,由于数值4及其以上至少可以拆分为两个正整数,我们可以只考虑2,3的情况,不需要做过多的计算比较。

class Solution {
    public int integerBreak(int n) {
        if(n < 4){
            return n - 1;
        }

        int[] dp = new int[n + 1];
        dp[2] = 1;
        for(int i = 3; i <= n; ++i){
            dp[i] = Math.max(Math.max(2 * (i - 2), 2 * dp[i - 2]), Math.max(3 * (i - 3), 3 * dp[i - 3]));
        }
        return dp[n];
    }
}

 复杂度分析

  •   时间复杂度:O(N)O(N)
  •   空间复杂度:O(N)O(N)

数学法

class Solution {
    public int integerBreak(int n) {
        if (n <= 3) {
            return n - 1;
        }
        int quotient = n / 3;
        int remainder = n % 3;
        if (remainder == 0) {
            return (int) Math.pow(3, quotient);
        } else if (remainder == 1) {
            return (int) Math.pow(3, quotient - 1) * 4;
        } else {
            return (int) Math.pow(3, quotient) * 2;
        }
    }
}

 复杂度分析

  •   时间复杂度:O(1)O(1)
  •   空间复杂度:O(1)O(1)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处: leetcode-cn.com/problems/in…