【陪伴式刷题】Day 36|动态规划|343.整数拆分(Integer Break)

刷题顺序按照代码随想录建议

题目描述

英文版描述

Given an integer n, break it into the sum of kpositive integers, where k >= 2, and maximize the product of those integers.

Return the maximum product you can get.

Example 1:

Input: n = 2 Output: 1 Explanation: 2 = 1 + 1, 1 × 1 = 1.

Example 2:

Input: n = 10 Output: 36 Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

Constraints:

  • 2 <= n <= 58

英文版地址

leetcode.com/problems/in...

中文版描述

给定一个正整数 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

中文版地址

leetcode.cn/problems/in...

解题方法

俺这版

这是第一反应写出的结果,看了题解貌似算是贪心的解法,其实就是根据推理找出规律,大家从1开始推到6、7左右一半就能看出规律了,因为超过4以后,继续分解之后的乘积就会大于原先的

  • 5=2+3 -> 2*3=6>5
  • 6=3+3 -> 3*3=9>6
  • ......

至于为什么是3,并没有进行严格的证明,也是找出的规律,14 < 2 3、15 < 24 < 3*3......不知道大家有没有印象,小时候学习长方形正方形的时候有个规律:周长是相同的时候,圆的面积>正方形面积>长方形的面积

java 复制代码
class Solution {
    public int integerBreak(int n) {
        if (n == 0 || n == 1) {
            return 0;
        }
        if (n == 2) {
            return 1;
        }
        if (n == 3) {
            return 2;
        }
        if (n == 4) {
            return 4;
        }
        int result = 1;
        while (n > 4) {
            n = n - 3;
            result = result * 3;
        }
        return result * n;
    }
}

复杂度分析

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

动态规划

这个动态规划的方法看是看懂了(应该看懂了吧),但是让我自己写真的是写不出写不出~~

java 复制代码
class Solution {
    public int integerBreak(int n) {
        //dp[i] 为正整数 i 拆分后的结果的最大乘积
        int[] dp = new int[n+1];
        dp[2] = 1;
        for(int i = 3; i <= n; i++) {
            for(int j = 1; j <= i-j; j++) {
                // 这里的 j 其实最大值为 i-j,再大只不过是重复而已,
                //并且,在本题中,我们分析 dp[0], dp[1]都是无意义的,
                //j 最大到 i-j,就不会用到 dp[0]与dp[1]
                dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
                // j * (i - j) 是单纯的把整数 i 拆分为两个数 也就是 i,i-j ,再相乘
                //而j * dp[i - j]是将 i 拆分成两个以及两个以上的个数,再相乘。
            }
        }
        return dp[n];
    }
}

复杂度分析

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

数学法

这个方法的时间复杂度、空间复杂度都是O(1),其实理论上他跟法1的逻辑是一样的,官方给出了证明:leetcode.cn/problems/in...

java 复制代码
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)
相关推荐
大数据编程之光13 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
Lenyiin23 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长26 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs30 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj12345678932 分钟前
JDK1.8新增特性
java·开发语言
繁依Fanyi43 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
m51271 小时前
LinuxC语言
java·服务器·前端
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
IU宝1 小时前
C/C++内存管理
java·c语言·c++