LeetCode 343.题整数分割题解

解法一

题目传送门

一、相关知识:

在高中的时候都学到过,N个数和一定时,其积有最大值,当且仅当这N个数相等时取得最大。

只有两个数时公式为:

a 2 + b 2 ≥ 2 a b ( 当 且 仅 当 a = b 时 等 号 成 立 ) a^2 + b^2 \ge2ab \left(当且仅当a=b时等号成立\right) a2+b22ab(a=b)

多个数时的公式:
1 + a 2 + a 3 + a 4 + a 5 + a 6 + ⋅ ⋅ ⋅ + a n n ≥ a 1 a 2 a 3 a 4 a 5 ⋅ ⋅ ⋅ a n n ( 当 且 仅 当 a 1 = a 2 = a 3 = ⋅ ⋅ ⋅ = a n 时 等 号 成 立 ) \frac{_1+a_2+a_3+a_4+a_5+a_6+···+a_n}{n}\ge\sqrt[n]{a_1a_2a_3a_4a_5···a_n} \\\left(当且仅当a_1=a_2=a_3=···=a_n时等号成立\right) n1+a2+a3+a4+a5+a6++anna1a2a3a4a5an (a1=a2=a3==an)

二、分析:(文中NumGiven为所给的整数)

根据这两个公式我们可以有一个大致的方向:尽量将正整数分为 m − 1 m-1 m1个大小大相同且为 n n n的正整数,和另外一个正整数,其中$ m=2、3、4···$

我们首先以整数 10 为例,10 可以被分为

拆分成的数集乘积
2   2   2   2   2 2\ 2\ 2\ 2\ 2 2 2 2 2 2 2 × 2 × 2 × 2 × 2 2\times2\times2\times2\times2 2×2×2×2×2
3   3   3   1 3\ 3\ 3 \ 1 3 3 3 1 3 × 3 × ( 3 + 1 ) 3\times3\times\left(3+1\right) 3×3×(3+1)
4   4   2 4 \ 4\ 2 4 4 2 4 × 4 × 2 4\times4\times2 4×4×2
5   5 5\ 5 5 5 5 × 5 5\times5 5×5

从上述表中我们可以看出,拆分出的相等的元素的个数为NumGiven/n,另外一个正整数为NumGiven%n

表中第二行为 3 × 3 × ( 3 + 1 ) 3\times3\times\left(3+1\right) 3×3×(3+1)是因为当余数为 1 时,拆分所得的 m − 1 m-1 m1个值为 n n n的正整数相乘再乘 1 的值远没有 m − 2 m-2 m2个值为 n n n的正整数相乘再与 n + 1 n+1 n+1相乘所得的结果大。(一个正整数共拆分为m个正整数)

当余数不为 1 时,拆分所得的 m − 1 m-1 m1个值为 n n n的正整数相乘再乘余数的值远比 m − 2 m-2 m2个值为 n n n的正整数相乘再与 n + 余 数 n+余数 n+相乘所得的结果大

推导如下:(令余数为r)
n m − 1 ⋅ r n m − 2 ⋅ ( n + r ) = n r n + r = r 1 + r n 因 为 r n < 1 且 由 上 述 假 设 r ≥ 2 所 以 可 得 n m − 1 ⋅ r n m − 2 ⋅ ( n + r ) > 1 \frac{n^{m-1}\cdot r}{n^{m-2}\cdot{\left(n+r\right)}}=\frac{nr}{n+r}=\frac{r}{1+\frac{r}{n}} \\因为\frac{r}{n}<1且由上述假设r\ge2所以可得 \\\frac{n^{m-1}\cdot r}{n^{m-2}\cdot{\left(n+r\right)}}>1 nm2(n+r)nm1r=n+rnr=1+nrrnr<1r2nm2(n+r)nm1r>1
到这,我们可以大概得出解题的流程:

  1. 求出NumGiven/n以及NumGiven%n的值。

  2. 如果NumGiven%n == 0则当前最大值为Pow(n,NumGiven/n-1),并且跳转至4,反之则跳转至3。

  3. 如果NumGiven%n == 1则当前最大值为Pow(n,NumGiven/n-1)*(n+1),反之当前最大值为Pow(n,NumGiven/n)*(NumGiven%n)

  4. 比较当前最大值与前一个最大值的大小,更新数据,变动n的值。

  5. 判断n是否大于NumGiven,若果是则跳转到5,反之跳转到1。

  6. 退出循环,输出最大值。

算法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

按照上述算法编写代码会出现当输入的整数位2,3时输出错误的现象,至于为什么会出现错误读者可带入算法进性检验。下面提供两种解决方案:

  1. 在算法最开始的时候判断输入的整数是否大于3,如果是则调用算法,反之则直接输出NumGiven-1
  2. 在程序中增加判断语言,对可能出现的错误现象进行修正,笔者采用的就是第二种方法。

代码如下:

int integerBreak(int n){
    int max=-1;				//设定初始的最大值位-1,便于对最大值进行覆盖填写
    
    int temp_max=1;			//存放当前最大值的变量	
    
    
    for(int i=2;i<n;i++)	//从2开始遍历直到n-1
    {
        
        int num=n/i;		//计算出该整数包含多少个n
        
        
        temp_max=pow(i,num);//按照分析的算法步骤先处理m-1个值为n的正整数,再对余数进行处理。
        
        if(n%i!=0)			//余数为0时,应直接返回数值,不能再乘余数
        {
            if(n%i==1&&num!=1)	//该步骤用于处理的正整数为3的特殊情况。
            temp_max=(temp_max/i)*(i+n%i);
            else`在这里插入代码片`
            temp_max*=n%i;
        }
        max = max>temp_max?max:temp_max;
        temp_max=1;
    }
    if (max==-1)			//该步骤用于处理输入的正整数位2的特殊情况
        return 1;
    return max;
}

解法二

一、分析:

通过解法一我们可以求出乘积的最大值,也可以求出当n值位多少时输出最大,再计算完58个实例之后发现,乘积的最大值总是在 n = 3 n=3 n=3处取得。下面对为什么总是再 n = 3 n=3 n=3处取得进行粗略的分析。

由解法一的分析我们可知,只有当被分成所有整数都相等时才能取得乘积最大,又因为要分成正整数。实现不了完全相等,这里我们先假设只需求得被分成所有数的乘积最大。于是可以列出下面的式子:
M a x     =     m a x { x n x } Max \ \ \ =\ \ \ max\{x^\frac{n}{x}\} Max   =   max{xxn}
式子中的x为均等分之后的值。使用Maltlab画出图像有:

在这里插入图片描述

该图像时从1到58对其进行均等分割并且相乘得到的图像,由图像可以粗略的看出当满足正整数条件的时候,x=3时乘积值最大,故由此可优化解法一,我们无需遍历,可直接默认分割得到的整数大部分都为3,即n=3。因此我们可以优化时间复杂度至 O ( 1 ) O(1) O(1)。代码与方法一大致相同,留做读者思考。

既然看到这里了,可以支持一下我的博客吗 ⇒ ⇒ ⇒ \Rightarrow\Rightarrow\Rightarrow 白羊的博客传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值