题目 343. 整数拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明:
你可以假设 n 不小于 2 且不大于 58。
简单介绍:
难度:中等
使用语言:JAVA。
这道题来自leetcode题库的数学标签。
解题思路:
首先看题、分析题意,我们可以明确一个关键点:
1.怎么拆分才能得到最大的乘积
既然,我们已经分析出来题目的关键任务了,下面我们就可以开始思考实现了。
我们采用算法与数据结构的思路来剖析一下这题,
数据结构:
要实现对数据的操作,我们要先明确存储数据的数据结构。
该题的数据结构的作用:
没有需要的特殊结构
推导:
此题纯数学推导,此处直接写结论
设将整数 n 拆分为 a 个小数字:n = n1 + n2 +…+ na
本题等价于求解:max(n1 × n2 ×…× na)
结论:
① 当所有拆分出的数字相等时,乘积最大。
② 最优拆分数字为 3 。
1.当 n≤3 时,按照规则应不拆分,但由于题目要求必须拆分,因此必须拆出一个因子 1,即返回n−1
2.当 n>3 时,求 n 除以 3 的 整数部分 a 和 余数部分 b (即 n = 3a + b),并分为以下三种情况:
- 当 b=0 时,直接返回 3^a;
- 当 b = 1 时,要将一个 1+3 转换为 2+2,因此返回 (3^a − 1 )× 4;
- 当 b = 2 时,返回 3^a × 2
算法:
class Solution {
public int integerBreak(int n) {
if(n <= 3) return n - 1;
int a = n / 3, b = n % 3;
if(b == 0) return (int)Math.pow(3, a);
if(b == 1) return (int)Math.pow(3, a - 1) * 4;
return (int)Math.pow(3, a) * 2;
}
}