剪绳子 --- 剑指Offer

剪绳子

给你一根长度为 n 绳子,请把绳子剪成 m 段(m、n 都是整数,2≤n≤58 并且 m≥2)。
每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少?
例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。
样例
输入:8
输出:18

思路

  1. 把一个正整数 N 拆分成若干正整数,只有有限种拆法N=n1+n2+…+nk,所以存在最大乘积。
  2. 为了求最大乘积,所以我们要避免拆出1。
  3. 假设ni > 5, ni 一定可以拆为 3 + (ni -3) = ni, 将3x(ni - 3)与ni做差,3x(ni - 3)-ni = 3ni - 9 - ni =2ni - 9.因为ni > 5,因此 一定有2ni - 9大于0,即 3 + (ni -3) > ni。所有,大于等于5的都会被往下拆成一个或多个3
  4. 假设ni为4,只能拆为2和2,因为不可能包含1,而 4=2*2,4没必要存在。以上证明N的拆分只可能包含2和3。并且最多两个2。

JS实现

    // const len = 8
    // const len = 4;
    const len = 5;
    const maxProductAfterCutting = function (length) {
        if (length <= 3) { return 1*(length-1) } // 2≤ length ≤58 并且 m≥2
        let multiple, surplus= length % 3; 
        // 0 => length能被3整除,
        // 1 => length 可以拆分为2X2+一个3的倍数
        // 2=> length 可以拆分为2+一个3的倍数
        if (surplus === 0) { // length 可分为 K个3
            multiple = Math.pow(3, Math.floor(length / 3)); 
        } else if(surplus === 1) {
            multiple = Math.pow(3, Math.floor(length / 3) - 1) * 4;
        } else if(surplus === 2) {
            multiple = Math.pow(3, Math.floor(length / 3)) * 2;
        }
        return multiple;
    };
    console.log(maxProductAfterCutting(len));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值