Integer Break | Leetcode 整数分解

343. Integer Break
整数分解

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).

例如2可以分解为1+1,乘积是1;10可以分解为3+3+4,乘积是36。

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

你可以假定n不小于2。

Hint:

提示:

There is a simple O(n) solution to this problem.

这个问题解法的复杂度是O(n)。

You may check the breaking results of n ranging from 7 to 10 to discover the regularities.

你可以从7到10的分解结果中寻找规律。


/*****************************************************************************************************************************/


先假设有一个任意大的n,它可以被完整地分成(x+x+x+…+x)的形式(假设x是连续的),一共n/x个,那么对于乘积y,就有y=x^(n/x).



求导:

两边先取对数。


定义域(x>0),又n>0,所以大于0。

令y’=0,得x=e。

当x<e时,y‘>0,y单调递增;

当x>e时,y’<0,y单调递减。

即当x=e时,y取得极值,此时乘积最大。


回到题目上来。

n和x都是正整数,e约等于2.7,位于2和3之间。

x=2时,y=2^(n/2)=1.414^n;

x=3是,y=3^(n/3)=1.442^n。

y(3) > y(2),因此x取3时更接近极值。

所以需要分解出尽量多的3。


一个数对3取余之后有0、1、2三个结果。

余数为0时,全部取3;

余数为1时,最后两个乘数是3和1,而1作为乘数是“浪费”掉的,1x3的乘积不如2x2大,所以取两个2相乘代替3和1相乘;

余数为2时,取一个2,其余全部取3。


因为至少要分解为两个整数,

所以从最小的n=2开始,分解为1+1,乘积是1;

n=3时,分解为1+2,乘积是2;

n=4时,对3取余等于1,分解为2+2;

n=5时,对3取余等于2,分解为3+2;

……


int integerBreak(int n) {
    int prod = 1;
    if (n == 2) prod = 1;
    if (n == 3) prod = 2;
    if (n >= 4) {
        while (n > 0) {
            if(n % 3 == 0){ n -= 3; prod *= 3;}
            if(n % 3 == 1){ n -= 4; prod *= 4;}
            if(n % 3 == 2){ n -= 2; prod *= 2;}
        }
    }
    return prod;
}


既然逻辑并不难,那么根据n>=4时对3取余的三种情况,找出prod和n的对应关系,可以无需循环。

n%3==0时,一共循环n/3次,乘积是3^(n/3),即(int)pow(3,n/3);

n%3==1时,循环了(n-1)/3次,乘积是4*3^((n-4)/3),即(int)(4*pow(3,(n-4)/3));

n%3==2时,循环了(n+1)/3次,乘积是2*3^((n-2)/3),即(int)(2*pow(3,(n-2)/3))。

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

 

时间复杂度取决于pow()函数,O(log(n))。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值