题目

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:输入: 2输出: 1解释: 2 = 1 + 1, 1 × 1 = 1。示例 2:输入: 10输出: 36解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-break

思路

给定正整数,将其拆分为至少两个正整数的和。这个问题能否用递归的方法来解呢,简要的分析可以得出答案是肯定的。

可能直接思考分割n比较抽象,我们先来思考一个小一点的数,比如先思考444是如何拆分的。下面画出递归树中的第一次分割:


要分割4,可以分割成1+?(这里的?表示可能为一个值,也可能是多个值)、2+?和3+?

其中只有1是不可再分的数字。

对于分割4来说,递归树如上。从上可以看出,存在重复子问题。并且分割1可以作为我们递归的终止条件。

如果仔细分析的话,还可以看出,分割1+3和分割3+1是同样的问题。因此,这里我们只需要分割到n//2+1即可。

下面画出分割n的示意图:

这样我们就简要的画出了分割n的递归树。下面我们先用递归的方法来解。

代码

递归

class Solution:# 定义递归方法def breakInteger(self,n):if n == 1:return 1max_result = -1for i in range(1, int(n//2) + 1): #从1分割到 n//2 + 1max_result = max(i * (n - i), i * self.breakInteger(n - i), max_result)return max_resultdef integerBreak(self, n: int) -> int:return self.breakInteger(n)

上面我们分析得知,可以通过从1分割到 n//2 + 1来加速算法。

重点来看下这段代码:
max_result = max(i * (n - i), i * self.breakInteger(n - i), max_result)

max_result = -1初始化为-1。然后比较当前最大值、直接用i * (n-i)(就是说不对n-i进行分割)、i * breakInteger(n - i)(对n-i进行分割后的最大值)三者之间的最大值,覆盖到max_result中。

最终返回最大值即可,下面看下提交结果。

果然递归的方式会超时。
但是我们不慌,因为我们会改写成记忆化搜索了(参阅LeetCode刷题之动态规划思想)。

记忆化搜索

dp = {}class Solution:def breakInteger(self,n):if n == 1:return 1if n not in dp:max_result = -1for i in range(1, int(n//2) + 1):max_result = max(i * (n - i), i * self.breakInteger(n - i), max_result)dp[n] = max_resultreturn dp[n]def integerBreak(self, n: int) -> int:return self.breakInteger(n)

改写成记忆化搜索也很简单,保存对传入的从参数n进行分割的结果即可。

动态规划

最后改写成动态规划的方式。

class Solution:def integerBreak(self, n: int) -> int:# 因为n不大于58,我们可以用一个列表来保存,dp[1]=1作为已知条件,值为-1表示未计算过dp = [1] * 2 + [-1] * (n-1) #dp[0]=1 ,dp[1] = 1, dp[2]到dp[n] = -1for i in range(2, n + 1):  # i从2到n# 依次计算出dp[i]for j in range(1,int(i/2)+1): # j从1到 i/2 + 1# 拆分为j 和 (i-j)dp[i] = max(dp[i], j * (i - j), j * dp[i - j]) #因为i-j < i的,而dp[i]在之前已经计算过了return dp[n]

这里用了两个循环,依次计算出2到n的分割最大值。

外层循环是2到n;内层循环用1到 i/2 + 1去分割i


这个题目动态规划的解法还没有记忆化搜索快。


在Python2中运行时间还是不错的。

在做完全平方数这个问题,自己写的解法需要几秒钟,不知道哪里写错了,就去看官方解法的时候,看到了这样一句话。

在LeetCode中提交时间Python3不知道为啥运行的时间超过Python2。 因此我尝试用Python2提交了一下,果然如此。

哈,以后就用Python2来写了。

LeetCode刷题——343. 整数拆分相关推荐

  1. LeetCode-动态规划基础题-343. 整数拆分

    描述 343. 整数拆分 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 示例 1: 输入: 2 输出: 1 解释: 2 = 1 + 1, 1 ...

  2. 学渣的刷题之旅 leetcode刷题 7.整数反转

    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 输入: 123 输出: 321 输入: -123 输出: -321 输入: 120 输出: 21 注意: 假设我们的环境只能存 ...

  3. leetcode - 343. 整数拆分

    343. 整数拆分 -------------------------------------------- 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获 ...

  4. 小何同学的leetcode刷题笔记 基础篇(01)整数反转

    小何同学的leetcode刷题笔记 基础篇(01)整数反转[07] *** [01]数学取余法*** 对数字进行数位操作时,常见的方法便是用取余的方法提取出各位数字,再进行操作 操作(1):对10取余 ...

  5. ​LeetCode刷题实战371:两整数之和

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  6. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串 22.4% 中等 10 正则表达式匹配 18.8% 困难 32 最长有效括号 23.3% 困难 44 通配符匹配 17.7% 困难 53 最 ...

  7. C#LeetCode刷题-数学

    数学篇 # 题名 刷题 通过率 难度 2 两数相加 29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 (a ...

  8. leetcode刷题目录总结

    题目 题目 技巧 相似的题目 其他 1. 无序数组中找出目标为target的两个数 先定义下一个数,然后找两位的数是否存在 高频, 大厂刷题班, 第27节 2.逆序链表两数相加 链表.各位加法 高频, ...

  9. LeetCode 刷题之路(python版)

    摘自:https://blog.csdn.net/qq_32384313/article/details/90745354 LeetCode 刷题之路(python版) 小坏wz 2019-06-02 ...

  10. ​LeetCode刷题实战354:俄罗斯套娃信封问题

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

最新文章

  1. Java项目:植物大战僵尸(java+swing)
  2. 和 杠精 聊Redis多线程 :(
  3. LeetCode 1311. 获取你好友已观看的视频(BFS+哈希map+vector排序)
  4. 【读书笔记《Android游戏编程之从零开始》】10.游戏开发基础(View 游戏框架)
  5. 【视频分享】尚硅谷Oracle视频教程
  6. [转]PT与PX区别
  7. C51 汇编和C语言编写从1加到100
  8. 计算机高级工程师职称评定条件,高级工程师职称评定条件是什么
  9. js截取url所带参数方法与url截取字段中包含中文会乱码的解决方案
  10. android apk 微信登入_图文详解Android集成微信登录的步骤
  11. 简洁明了的深度优先遍历算法
  12. 【百度地图】折线图平面图
  13. 【入门】Pytorch实现简单的图片分类器
  14. 机器学习(周志华著)习题 第03章 线性模型
  15. mac删除自带的 ABC 输入法
  16. #离散#ssl 1747 登山机器人问题
  17. Happy Birthday! My Motherland!
  18. 步进电机不知道线序颜色的情况下如何区分线序
  19. 无人机航测是选择固定翼还是多旋翼?
  20. Typora使用千牛云图床快速配置

热门文章

  1. 小议数据库主键选取策略(转)
  2. Splash args 属性
  3. 工业机器人常用语言---val语言介绍
  4. 4——编码规则以及vim的使用和虚拟环境
  5. 有哨兵的双向循环链表、单向循环链表
  6. ubuntu17.04新安装之后的软件准备
  7. 秒杀的倒计时按钮实现
  8. Android ListView显示底部的分割线
  9. 服务器监控之 ping 监控
  10. BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草(动态规划)