作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/integer-break/description/

题目描述

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.

Example 1:

Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.

Example 2:

Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

Note: You may assume that n is not less than 2 and not larger than 58.

题目大意

一个整数可以拆分成几个较小的整数之和。求如何拆分才能使这几个较小的整数乘积最大。

解题方法

数学解法

也是一个扔了几个月的题目。有时候会发现,扔了很久的题目,不是太难,而是方法比较少见,其实很简单的罢了。

这个题,我是看了[LeetCode] Integer Break 整数拆分才懂的。下面把分析引用如下:

这道题给了我们一个正整数n,让我们拆分成至少两个正整数之和,使其乘积最大,题目提示中让我们用O(n)来解题,而且告诉我们找7到10之间的规律,那么我们一点一点的来分析:

正整数从1开始,但是1不能拆分成两个正整数之和,所以不能当输出。

那么2只能拆成1+1,所以乘积也为1。

数字3可以拆分成2+1或1+1+1,显然第一种拆分方法乘积大为2。

数字4拆成2+2,乘积最大,为4。

数字5拆成3+2,乘积最大,为6。

数字6拆成3+3,乘积最大,为9。

数字7拆为3+4,乘积最大,为12。

数字8拆为3+3+2,乘积最大,为18。

数字9拆为3+3+3,乘积最大,为27。

数字10拆为3+3+4,乘积最大,为36。

那么通过观察上面的规律,我们可以看出从5开始,数字都需要先拆出所有的3,一直拆到剩下一个数为2或者4,因为剩4就不用再拆了,拆成两个2和不拆没有意义,而且4不能拆出一个3剩一个1,这样会比拆成2+2的乘积小。那么这样我们就可以写代码了,先预处理n为2和3的情况,然后先将结果res初始化为1,然后当n大于4开始循环,我们结果自乘3,n自减3,根据之前的分析,当跳出循环时,n只能是2或者4,再乘以res返回即可。

我试着证明一下:

当m,n>=2时,有m * n >= m + n。所以把一个整数(m+n)拆开成较小整数(m,n>=2)之后的乘积(m*n)会比原整数(m+n)更大。由归纳法,当拆开的较小整数(m,n)>=4或5时,可以把大于等于4,5的整数拆成更小的整数2和3从而得到不小于4,5的乘积。总之,把任意整数拆成若干2和3的和,此时得到的乘积是最大的。

这里需要说明任意大于等于2的正整数N都能拆解成2x + 3y,其中x,y属于自然数。 2x + 3y = 2*(x + y) + y。由这个式子可知,当y = 1时,该式子能表示出所有>=3的奇数;当y = 0时,该式子能表示出所有>=2的偶数。因此N = 2x+3y至少有一组解。

下面需要求解的是N = 2x + 3y时,如何分配x,y才能使得target = 2^x * 3^y是最大的。

首先有y = (N - 2 * x)/3,优化的目标函数两边同时取对数得,log(target) = xlog2 + ylog3.

⇒ log(target) = x * log2 + ((N - 2 * x) / 3) * log3
⇒ x * log2 + (N/3) * log3 - (2x/3) * log3
⇒ (log2 - 2/3 * log3) * x + N/3 * log3
⇒ -0.017 * x + N/3 * log3

由于要优化的log(target)是递增函数,而右式是个递减函数,所以当x越小,则log(target)越大。

综上可知,我们应该把n拆成若干2和3的和,其中2的个数尽可能少,3的个数尽可能多。得到的所有2和3的乘积就是最大乘积。

python代码如下:

class Solution:
def integerBreak(self, n):
"""
:type n: int
:rtype: int
"""
if n == 2: return 1
if n == 3: return 2
res = 1
while n > 4:
res *= 3
n -= 3
return res * n

C++代码如下:

class Solution {
public:
int integerBreak(int n) {
if (n == 2) return 1;
if (n == 3) return 2;
int res = 1;
while (n > 4) {
res *= 3;
n -= 3;
}
return res * n;
}
};

动态规划

这个题的动态规划公式是dp[i] = dp[i - 3] * 3,当n >= 7时成立。

class Solution(object):
def integerBreak(self, n):
"""
:type n: int
:rtype: int
"""
dp = [0, 0, 1, 2, 4, 6, 9]
for i in range(7, n + 1):
dp.append(dp[i - 3] * 3)
return dp[n]

日期

2018 年 5 月 28 日 —— 太阳真的像日光灯~
2019 年 1 月 24 日 —— 快要回家了

【LeetCode】343. Integer Break 解题报告(Python & C++)的更多相关文章

  1. LN : leetcode 343 Integer Break

    lc 343 Integer Break 343 Integer Break Given a positive integer n, break it into the sum of at least ...

  2. [LeetCode] 343. Integer Break 整数拆分

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  3. leetcode@ [343] Integer Break (Math & Dynamic Programming)

    https://leetcode.com/problems/integer-break/ Given a positive integer n, break it into the sum of at ...

  4. leetcode 343. Integer Break(dp或数学推导)

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  5. Leetcode 343. Integer Break

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  6. 【LeetCode】Word Break 解题报告

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  7. 【LeetCode】397. Integer Replacement 解题报告(Python)

    [LeetCode]397. Integer Replacement 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/inte ...

  8. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  9. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

随机推荐

  1. 36-Same Tree

    Same Tree My Submissions QuestionEditorial Solution Total Accepted: 126116 Total Submissions: 291884 ...

  2. App内容分享

    1.发送文本内容 发送简单的数据到其他应用,比如社交分分享的内容,意图允许用户快速而方便的共享信息. //分享简单的文本内容 public void btnShareText(View view) { ...

  3. "delete this" in C++

    Ideally delete operator should not be used for this pointer. However, if used, then following points ...

  4. 【编程思想】【设计模式】【结构模式Structural】代理模式Proxy

    Python版 https://github.com/faif/python-patterns/blob/master/structural/proxy.py #!/usr/bin/env pytho ...

  5. java关键字volatile内存语义详细分析

    volatile变量自身具有下列特性. 1.可见性.对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写 入. · 2.原子性:对任意单个volatile变量的读/ ...

  6. Java学习1:图解Java内存分析详解(实例)

    首先需要明白以下几点: 栈空间(stack),连续的存储空间,遵循后进先出的原则,用于存放局部变量. 堆空间(heap),不连续的空间,用于存放new出的对象,或者说是类的实例. 方法区(method ...

  7. 【Python】数据处理分析,一些问题记录

    不用造轮子是真的好用啊 python中单引号双引号的区别 和cpp不一样,cpp单引号表示字符,双引号表示字符串,'c'就直接是ascii值了 Python中单引号和双引号都可以用来表示一个字符串 单 ...

  8. 【Jenkins系列】-备份机制

    Jenkins是主从模式,从节点可以做集群.负载,从而实现从节点的高可用,但是主节点是单节点,一旦主节点宕机,会导致Jenkins服务不可用.Jenkins主节点本身是不支持集群的,需要通过其他变通方 ...

  9. AI 2021 年度报告

    建议大伙有空还是自己亲自读一下,虽然有点长,188页ppt. https://docs.google.com/presentation/d/1bwJDRC777rAf00Drthi9yT2c9b0Ma ...

  10. Java Web三大组件之过滤器(Filter)

    什么是过滤器?有什么用? 过滤器JavaWeb三大组件之一,它与Servlet很相似.不过滤器是用来拦截请求的,而不是处理请求的.过滤,顾名思义,就是留下我们想要的,丢掉我们不需要的.例如:某个网站的 ...