给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
例如,给定 n = 2,返回1(2 = 1 + 1);给定 n = 10,返回36(10 = 3 + 3 + 4)。
注意:你可以假设 n 不小于2且不大于58。
思考:
一个正整数可以被拆分成若干个正整数,如何使拆分出的正整数乘积最大?
此题明显是不能用有穷遍历的,关键点在于找出使乘积最大的规律。
按照题目拆分为至少两个正整数的要求,
2只能拆分为1和1,返回1
3可以拆分为1和2,返回2
4可以拆分为2和2,返回4
5可以拆分为2和3,返回6
6可以拆分为3和3,返回9
7可以拆分为2、2、3,返回12
到这里规律似乎明显了,所有的数最终都可以拆分出若干个2和3,2是最小的偶质数,3是最小的奇质数。
6可以拆分为3、3,也可以拆分成2、2、2,显然3、3的乘积更大。
所以到这里总结一下规律,如果正整数n小于3,则返回n-1,如果n>=3,则将n拆分为若干个2和3,且优先拆分出3。
按照优先拆分出3的原则,可以使用一个递归完成:
从数字n大于3,从中拆分出一个3,再将n-3重复这个过程,直到n-3小于等于3。
又因为4可以拆为2、2,4=2*2,所以若n-3为4,也可以停止递归。
public int integerBreak(int n) {
if (n <= 3) {
return n - 1;
}
if (n == 4) {
return 4;
}
// 若n-3<=3,停止递归,又因为4可以拆为2、2,4=2*2,所以若n-3为4,也可以停止递归。
if (n - 3 <= 4) {
return 3 * (n - 3);
}
return 3 * integerBreak(n - 3);
}