剑指 Offer 14- I. 剪绳子
2021-09-08 11:52
399 查看
剑指 Offer 14- I. 剪绳子
给你一根长度为 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:
输入: 2 输出: 1 解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
提示:
- 2 <= n <= 58
一、动态规划
首先使用动态规划解决问题,最重要的就是理解dp数组的含义。 此处的dp[i] 表示长度为i的绳子剪成m段后的最大乘积。初始化dp[2] = 1 表示如果一个绳子长度为2必然只能分成两段长度为1的绳子,两者的乘积为1。
- 然后尝试对绳子进行分割,如果只剪掉长度为1,对最后的乘积无任何增益,所以从长度为2开始剪,代码中的j就是表示尝试剪的长度。
- 剪下一段后,剩余部分可以剪也可以不剪。如果不剪则得到的长度乘积为
j * (i - j)
。如果剪得到的长度为j * dp[i - j]
两者取最大值 - 不断修改剪的长度j (j范围为[2, i -1])。从所有结果中找到最大值即为dp[i]的结果。
- 从而有状态转移方程
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
class Solution { public int cuttingRope(int n) { // dp[i]表示长度为i的绳子被剪成m段,每段乘机的最大值 int[] dp = new int[n+1]; // 因为m>1,所以dp[2] = 1而不是2 dp[2] = 1; // i表示绳子长度 for (int i=3;i<=n;++i){ // i-j >= 2。j代表第一次剪掉的长度,剪掉1没用,所以从2开始,剩余的长度i-j怎么减直接取dp[i-j] for (int j=1;j<=i-2;++j){ // 这里因为m>1,所以dp[2] = 1而不是2,dp[3]不能是dp[2] * 1,这样答案是1,错误. // 因此下面要添加Math.max(dp[i-j], i-j)。 dp[i] = Math.max(Math.max(dp[i-j], i-j) * j, dp[i]); } } return dp ; } }
二、贪心算法
这个做题思路直接引用K神吧,直接给跪了。
算法流程:
- 当 n ≤3 时,按照规则应不切分,但由于题目要求必须剪成 m>1 段,因此必须剪出一段长度为 11 的绳子,即返回 n - 1。
- 当 n>3时,求 nn 除以 33 的 整数部分 aa 和 余数部分 bb (即 n = 3a + b ),并分为以下三种情况: 当 b = 0 时,直接返回 3^a ;
- 当 b = 1时,要将一个 1 + 3转换为 2+2,因此返回 3^ ×4;
- 当 b = 2时,返回 3^a × 2。
class Solution { public int cuttingRope(int n) { if(n <= 3) return n - 1; int a = n / 3, b = n % 3; if(b == 0) return (int)Math.pow(3, a); if(b == 1) return (int)Math.pow(3, a - 1) * 4; return (int)Math.pow(3, a) * 2; } }
其实K神还有更详细的求导过程和推论过程,建议点参考链接详细再看看。
参考链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/mian-shi-ti-14-i-jian-sheng-zi-tan-xin-si-xiang-by/
相关文章推荐
- 【Golang】LeetCode-剑指Offer-面试题14- I-剪绳子【两种写法】
- 剑指Offer 面试题14 剪绳子
- [剑指Offer] 14_剪绳子
- 剑指 Offer 14- II. 剪绳子 II
- 剑指 Offer 14- I. 剪绳子
- 【剑指offer】面试题14:剪绳子
- 剑指 Offer 14- II. 剪绳子 II
- 剑指Offer-14:剪绳子
- 剑指Offer面试题14:剪绳子 Java代码实现
- 剑指offer--面试题14:剪绳子
- 剑指offer-3-面试14:调整数组顺序使奇数位于偶数前面
- 剑指Offer:面试题14 调整数组顺序使奇数位于偶数掐面
- 剑指offer----015(剪绳子)
- 剑指offer--面试题14
- 剑指Offer---面试题14:调整数组,使奇数位于偶数前
- 剑指offer代码解析——面试题14调整数组顺序使奇数在偶数之前
- 剑指offer-14 判断树的子结构
- 剑指offer面试题14 调整数组顺序使奇数位于偶数前面
- 【剑指offer】剪绳子 -- Python 实现
- 剑指offer 14 - 调整数据顺序使奇数位于偶数前面