LeetCode343 整数拆分详解
题目详情
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
题目解析
关键是找到状态方程, 我们设置dp[i]表示整数i的最大乘积, 那么把问题分成子问题, 我们发现dp[i] 与前面的dp[1] ~ dp[i-1]都有关系, 关系很容易找到
dp[i] = max(j * (i-j), j * dp[i - j]) j = 1,2 ······ i -1
而初始条件dp[1] = 1, dp[2] = 2, dp[3] = 3
为什么要加上 j * (i-j)的比较呢, 是为了处理dp[i] < i的情况, 例如
n=4, 那么如果不考虑 j * (i-j), 因为dp[2] = 1 <2, 所以最终的结果为3, 但是其实把4分成2 * 2, 最终结果为4. 所以要加上 j * (i-j) 直接把i分成两个数字i, j-i,的情况。
那么可以由此得到第一种dp代码
代码一 动态规划
class Solution {
public:
int integerBreak(int n) {
vector <int> dp(n +1, 0);
int tmp = 0;
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for (int i = 3; i <= n ; i++) {
tmp = 0;
for (int j = 1; j <= i - 1; j++) {
tmp = max(tmp, max(dp[j] * (i-j), j * (i - j)));
}
dp[i] = tmp;
}
return dp[n];
}
};
时间复杂度为0(n^2)
代码2 数学推倒
有一些其他的博客给了更加速度快的算法, 有一种是利用数学推导, 得出要想使乘积最大, 只需要尽可能的多分成3, 其次是二
数学推导过程
由均值不等式(n个数的算术平均数大于等于它们的几何平均数):

得:当把输入的n拆分成几个相等的数时它们的积最大。
那么问题来了,拆分成几个呢?
为了方便使用导数,我们先假设我们可以把n拆分成实数。那么设每一个数为x,则一共有n/x个数。
设它们的积为f(x),则f(x)=x(n/x),那么怎么求f(x)最大值呢?求导数!
f′(x)=(n/x2) * x(n/x) * (1-lnx)
当x=e时取极大值。
而我们题目里规定x为整数,那么我们只需要取的x越靠近e越好。那么2<e<3,而且e=2.71828…,所以取3是最好的,如果取不到3就取2。
幂运算复杂度为O(lgn),所以这个算法复杂度为O(lgn)。
代码如下
class Solution {
public:
int integerBreak(int n) {
if(n == 2)
return 1;
else if(n == 3)
return 2;
else if(n%3 == 0)
return pow(3, n/3);
else if(n%3 == 1)
return 2 * 2 * pow(3, (n - 4) / 3);
else
return 2 * pow(3, n/3);
}
};
LeetCode343 整数拆分详解的更多相关文章
- [Swift]LeetCode343. 整数拆分 | Integer Break
Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...
- 【转】linux 原子整数操作详解
原文网址:http://blog.csdn.net/hunanchenxingyu/article/details/8994379 printk(“%d\n”,atomic_read(&v)) ...
- Extjs6(特别篇)——项目自带例子main.js拆分详解
本文基于extjs6.0.0 一.拆分代码来看看 1.主页面main是个tab页: 写一些页面的依赖: 标明页面的controller和viewModel Ext.define('Learning.v ...
- MySQL 水平拆分与垂直拆分详解
前言:说到优化mysql,总会有这么个回答:水平拆分,垂直拆分,那么我们就来说说什么是水平拆分,垂直拆分. 一.垂直拆分 说明:一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将 ...
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- 详解CorelDRAW中如何合并与拆分对象
合并两个或多个对象可以创建带有共同填充和轮廓属性的单个对象,以便将这些对象转换为单个曲线对象.可以合并的对象包括矩形.椭圆形.多边形.星形.螺纹.图形或文本等,本教程将详解CorelDRAW中关于合并 ...
- 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)
本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...
- Hadoop MapReduce执行过程详解(带hadoop例子)
https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...
- CSS详解
Web前端开发css基础样式总结 颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255 ...
随机推荐
- 量子点/钙钛矿 LED的研究概述
注:参考文献和文章尚在整理ing... 一 常用术语 1.外量子效率(External quantum efficiency,EQE) 这是LED最重要的参数,它的定义为: 因此,EQE越大,发射到外 ...
- java基础知识--数据类型
计算机时识别不了我们编写的代码语言,计算机中的数据全部采用二进制表示,即0和1表示的数字,每一个0或者1就是一个位,一个位叫做一个bit(比特).(实际上计算机只能识别高低电平,而不是0和1.) 字节 ...
- js 从目标数组中过滤掉 一个数组元素,
标题描述的有点僵硬,大概需求是,从目标数组中过滤掉我想要删除的元素集合,这里使用的是遍历+过滤器的组合,很方便,做个笔记! let old = ["AE_CN_SUPER_ECONOMY_G ...
- sqlite 显示表内容时乱码,无法正常显示汉字,
把txt文件另存为时,选择编码为utf-8即可
- 大家是怎么做APP接口的版本控制的?欢迎进来看看我的方案。升级版的Versioning
背景 APP不同于网站,网站程序一发版,所有用户看到的都是最新的页面.调用最新的接口,没有新老版本一说.APP一旦下载到用户手机上,用户不更新你拿他一点办法都没有,但是随着业务的调整,同一个接口的请求 ...
- react 阻止事件传递/冒泡
当我们设计界面时,在以下情况会需要阻止元素/组件内的事件阻断,不被上层触发: 弹出提示框,期望点击框外空白区域可以关闭弹框.点击框内不关闭弹框 组件设计时,期望点击全局/点击指定元素时,显示不一样的交 ...
- linux创建逻辑卷(lv)并挂载
新加磁盘启动系统后,查看现有磁盘使用情况 命令 df -h 查看现有磁盘情况,我们发现系统已经有一个10G的磁盘sdb,这个磁盘共有1305个柱面,每个柱面大小是8225280 bytes (大约8M ...
- 算数组的长度cpp
今天被自己整傻了.... cpp int 型的数组就别想用strlen来求长度了,会报错的. (当然java 里直接用length就可以了...) 所以我建议用vector!!!!!!
- string类型 C++
(C++递归预习到了string类型,这个是处理字符串的一个非常好用的东西,在C里面没有.今天来学习一下) 顺便推荐一个很不错的网站:http://c.biancheng.net/view/400.h ...
- 01_Linux基础篇
学于黑马.传智播客.尚硅谷 感谢 黑马官网 传智播客官网 尚硅谷官网 微信搜索"艺术行者",关注并回复关键词"linux"获取视频和教程资料! b站在线视频 第 ...