《剑指 Offer》——67、剪绳子

1. 本题知识点

贪心算法

2. 题目描述

现在有一根长度为 n 的绳子,请你把它任意剪成 m 段,请问每一段绳子长度的乘积最大值是多少?(n>1,m>1)

例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18。

Input
绳子长度:8
Output
最大乘积:18

3. 解题思路

贪心算法

  1. 首先,这道题给了我们限制条件(总绳子长度为 n)。然后,它希望我们在满足限制条件的情况下,求期望值最大(每一段绳子长度的乘积最大值),我们就应该联想到贪心算法了。
  2. 如果满足每一段绳子的长度都是最优解(各个子问题都是局部最优解),那么每一段绳子长度的乘积就是最大值(整个问题就是最优解),那这道题就可以用贪心算法来解决。

我们先列举几种最大乘积的情况

n最大乘积
21x1 = 1
32x1 = 2
42x2 = 4
53x2 = 6
63x3 = 9
73x2x2 = 12
83x3x2 = 18
93x3x3 = 27
103x3x2x2 = 36
113x3x3x2 = 54
123x3x3x3 = 81

可以发现:

  • 当 n = 2,n = 3 时,只有在这两种情况下,出现了剪一段绳子的长度是 1,所以我们把它们当作特殊情况。

  • 当 n > 3 时,剪一段绳子的长度要么是 2,要么是 3,并且优先是 3(因为 3x3 > 2x2x2)

  • 出现长度为 2 的绳子只有两种情况:

    • 前面都是长度为 3,最后一段绳子长度为 2(比如:n = 8,剪为 3x3x2)
    • 假设前面都是长度为 3,最后一段绳子长度为 1,此时会拿出一个长度为 3 和长度为 1 的绳子,把它们换为两段长度为 2 的绳子。(比如:n = 7,假设剪为 3x3x1,这时就换成 3x2x2,因为 2x2>3x1)

4. 代码

public class Solution {
    /**
     * 输入绳子长度 target,将它剪成若干段后,返回每一段绳子长度的乘积最大值
     * @param target
     * @return
     */
    public int cutRope(int target) {
        if (target == 2) {
            return 1;
        } else if (target == 3) {
            return 2;
        } else {
            // 最多能剪出长度为 3 的绳子数量
            int numOfThree = target / 3;
            // 最后一段绳子的长度
            int LengthOfLast = target % 3;
            // 当最后一段长度为 2 时
            if (LengthOfLast == 2) {
                return (int) (2 * Math.pow(3, numOfThree));
            }
            // 当最后一段长度为 1 时
            else if (LengthOfLast == 1) {
                return (int) (2 * 2 * Math.pow(3, numOfThree - 1));
            }
            // 当每一段长度都为 3 时
            else {
                return (int) Math.pow(3, numOfThree);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值