🧮 Algorithm Notebook
1、算法准备
1.1 牛客网编程OJ的典型输入输出
2、算法框架
2.1 动态规划
2.1.1 斐波那契数列
2.1.2 背包问题
2.1.3 贪心算法
2.1.4 序列和数组类问题
2.1.5 编辑距离
2.1.6 高楼扔鸡蛋
2.1.7 股票问题系列通解
2.1.8 最长有效括号
2.1.9 剪绳子
2.1.10 正则表达式匹配
2.2 二分查找
2.2.1 二分查找框架
2.2.2 搜索旋转排序数组
2.3 链表
2.3.1 反转链表
2.3.2 相交链表
2.3.3 合并链表
2.3.4 链表中倒数第k个节点
2.3.5 复制带随机指针的链表
2.4 排序算法
2.4.1 常见排序算法
2.5 二叉树
2.5.1 二叉树遍历
2.5.2 岛屿问题
2.5.3 二叉树路径问题
2.5.4 构造二叉树
2.6 回溯算法
2.6.1 回溯算法解题框架
2.6.2 N皇后
2.7 数组
2.7.1 删除有序数组中的重复项
2.7.2 滑动窗口最大值
2.7.3 调整数组顺序使奇数位于偶数前面
2.7.4 螺旋矩阵
2.7.5 多数元素
2.7.6 最大数
2.7.7 和为s的两个数字
2.7.8 构建乘积数组
2.7.9 两数之和
2.8 字符串
2.8.1 最小覆盖子串
2.8.2 比较版本号
2.8.3 验证IP地址
2.8.4 基本计算器 II
2.8.5 字符串解码
2.8.6 移掉 K 位数字
2.8.7 无重复字符的最长子串
2.8.8 第一个只出现一次的字符
2.8.9 翻转字符串里的单词
2.8.10 字符串转换整数 (atoi)
2.8.11 字符串四则运算
2.9 栈
2.9.1 最小栈
2.9.2 弹出序列
2.10 数学
2.10.1 用 Rand7() 实现 Rand10()
2.10.2 只出现一次的数字
2.10.3 整数反转
2.10.4 求1+2+…+n
2.10.5 二进制中1的个数
2.10.6 幂运算
2.10.7 1~n 整数中 1 出现的次数
2.10.8 数字序列中某一位的数字
2.10.9 丑数
2.10.10 n个骰子的点数
2.10.11 圆圈中最后剩下的数字
2.10.12 不用加减乘除做加法
2.10.13 x 的平方根
2.11 设计
2.11.1 LRU 缓存机制
-
+
tourist
register
Sign in
剪绳子
## 1 题目 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n 都是整数,n>1 并且 m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18。 **示例 1:** ```txt 输入: 2 输出: 1 解释: 2 = 1 + 1, 1 × 1 = 1 ``` **示例 2:** ```txt 输入: 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36 ``` **提示:** * 2 <= n <= 58 > 相似题目: > > 1. [剑指 Offer 14- II. 剪绳子 II](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof)。 ## 2 问题分析 1. 首先**定义函数 $f(n)$ 为把长度为 $n$ 的绳子剪成若干段后各段长度乘积的最大值**。 2. **在剪第一刀的时候**,**我们有 $n - 1$ 种可能的选择**,**也就是剪出来的第一段绳子的可能长度分别为 $ 1, 2, ..., n - 1$**,因此 $f(n) = max(f(i) \times f(n - i))$,其中 $ 0 < i < n$。 3. **这是一个从上至下的递归公式**,**由于递归会有很多重复的子问题**,**从而有大量不必要的重复计算**,**一个更好的方法是按照从下而上的顺序计算**,**也就是说我们先得到 $f(2)$**、**$f(3)$**,**再得到 $f(4)$**、**$f(5)$**,**直到得到 $f(n)$**。 4. **当绳子长度为 2 时**,**只可能剪成长度都为 1 的两段**,**因此 $f(2)$ 等于 1**,**当绳子的长度为 3 时**,**可能把绳子剪成长度分别为 1 和 2 的两段或者长度都为 1 的三段**,**由于 $ 1 \times 2 > 1 \times 1 \times 1$**,**因此 $f(3) = 2$**。 ## 3 参考代码 ```java /** * 剑指 Offer 14- I. 剪绳子 * @param n 绳子长度 * @return 剪成 m 段后所有段长的最大乘积 */ public int cuttingRope(int n) { // dp 数组,其中 dp[i] 表示长度为 i 的绳子剪成 m 段后所有段长的最大乘积 int[] dp = new int[n + 1]; if (n == 2) {return 1;} if (n == 3) {return 2;} dp[0] = 0; dp[1] = 1; dp[2] = 2; dp[3] = 3; for (int i = 4; i <= n; i++) { for (int j = 1; j <= i / 2; j++) { // 转移方程 dp[i] = Math.max(dp[i], dp[j] * dp[i - j]); } } // 返回最后结果 return dp[n]; } ``` ## 参考文献 1. [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof)。 2. [无需复杂数学!二元基本不等式分析动态规划、贪心算法](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offermian-shi-ti-14suan-fa-zhon-6bxx)。 3. [剑指 Offer-14:剪绳子](https://blog.csdn.net/Koala_Tree/article/details/78932316)。 4. [剑指 Offer 14- II. 剪绳子 II](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof)。
ricear
Feb. 8, 2022, 3:53 p.m.
©
BY-NC-ND(4.0)
转发文档
Collection documents
Last
Next
手机扫码
Copy link
手机扫一扫转发分享
Copy link
Markdown文件
share
link
type
password
Update password