LeetCode 343.Integer Break题解

题目

题目链接
随机给你一个大于2的正整数,让你将其拆分(这意味这至少将其拆分为两个数),比如10可以拆分为3+3+4。最后你需要得出一种拆分方式,使得所有数之积最大。10的结果为3*3*4=36

思路

数学方法

有大佬经过观察,得出结论:

1.要想得到最大值,需要将所有的数拆分成2或3
2.能拆分成3就优先考虑3

这个链接的解释说得很清楚,大家可以看一下。

我的思路

这道题属于动态规划类的,我就琢磨着怎么找到转移方程。

  1. 我们可以先开辟一个数组dp[n+1],保证每个dp[i]保存对应数字i的最大拆分结果
  2. 那么,我们通过遍历i之前的所有最大拆分结果dp[j],结果dp[i] = Math.max( dp[i], dp[j] * (i-j) );

看似思路很对,但里面还有一个坑。我们有两个特殊的数字需要处理:23dp[2] = 1dp[3] = 2,这两个数字是两个最大拆分结果小于本身的数字,所以如果j为2或3,我们不如使用j本身,反而比使用dp[j]更大。

代码实现(Java)

public int integerBreak(int n) {
        int[] dp = new int[n+1];
        dp[1] = 1;
        dp[2] = 1;

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

你可能感兴趣的:(leetcode)