Leetcode 343. Integer Break

原题链接:

343. Integer Break

343. Integer Break

    My Submissions
Total Accepted: 642  Total Submissions: 1506  Difficulty: Medium

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

Note: you may assume that n is not less than 2.

Hint:

  1. There is a simple O(n) solution to this problem.
  2. You may check the breaking results of n ranging from 7 to 10 to discover the regularities.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

Hide Tags
  Dynamic Programming Math


思路:

      乍一看,很明显的一道动态规划题目,而且很容易想到的是O(n^2)的解法。


解法一:DP O(n^2)解法

int integerBreak(int n) {
        vector<int> dp(n + 1, 1);
        
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= i + 1; ++j)
            {
                if(i + j <= n)
                {
                    dp[i + j] = max(max(dp[i], i) * max(dp[j], j), dp[i + j]);
                }
            }
        }
        
        return dp[n];
    }


恩,Hint提示说有O(n)的解法,让我们从7-10这些数的结果中找规律。

n = 2 max = 1(1 + 1)

n = 3 max = 2(1 + 2)

n = 4 max = 4(2 + 2)

n = 5 max = 6(2 + 3)

n = 6 max = 9(3 + 3)

n = 7 max = 12(3 + 2 + 2)

n = 8 max = 16(2 + 2 + 2 + 2)

n = 9 max = 27(3 + 3 + 3)

n = 10 max = 36(2 + 2 + 3 + 3)

大致也发现了一点规律,我们都分解为1 2 3这样的组合。

很简单,如果组合为4,4又可以分解为2 + 2,如果组合为5,5又可以分解为2 + 3。

以此类推~


上面还有一个规律,如果一个数分解后可以写成全是2或全是3,那么全是3的乘积肯定比全是2的大。

比如6 = 2 + 2 + 2 = 3 + 3 肯定是3*3 > 2*2*2。


所以基于上面的思路,可以写出O(n)的代码了:

int integerBreak(int n) {
        if(n <= 3) return n - 1;
        
        vector<int> dp(n + 1, 0);
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        
        for(int i = 4; i <= n; ++i)
        {
            dp[i] = max(2 * dp[ i - 2], 3 * dp[i - 3]);
        }
        
        return dp[n];
    }

下面写点数学公式:

对于n≥4

n = 4 max = 4 

n > 4   下面这个等式肯定是正确的。

              3 * (n - 3) > n

上面这个式子说明:将n分解为3 和 n - 3,乘积变大了,对不对。

【不要问我为什么分解为3和n-3


上面分解为2的乘积比分解为3乘积小,系不系?

如果能分解为3,何乐不为呢?

大致这么解释吧~】


继续n-3,按照上面这个规律分解下去。

恩,第二种解法出来了~

解法二:递归 

int integerBreak(int n) {
    int a[5] = {1, 2, 4, 6, 9};
    
    if(n <= 6) return a[n - 2];
    else return 3 * integerBreak(n - 3);
}


OK,上面这个思路转化下,其实就是能分解为3,就尽可能分解为3,

分为下面几种情况:

n % 3 == 0  就全部分解为3。

n % 3 == 1 肯定有个4,剩下的分解为3。

n % 3 == 2 有个2,剩下的全部分解为3。

所以,代码也可以这么写~

int integerBreak(int n) {
    if(n <= 3) return n - 1;
    if(n % 3 == 0) return pow(3, n / 3);
    if(n % 3 == 1) return 4 * pow(3, (n - 4) / 3);
    if(n % 3 == 2) return 2 * pow(3, n / 3);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值