剑指offer-剪绳子

剪绳子

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案

解题思路

这道题解题思路各式各样,贪心算法更符合本题的立意吧。
贪心算法

  • 贪心规则
    最高优先级:3。把绳子尽可能切为多个长度为3的片段,留下的最后一段绳子的长度可能为0,1,2三种情况。
    次高优先级:2。若最后一段绳子长度为2,则保留,不再拆为1+1。
    最低优先级:1。 若最后一段绳子长度为1;则应把最后的3 + 1替换为2 + 2,因为2×2>3×1。
    关于优先级的确定看下面的严谨的数学推导整数拆分-数学方法。
  • 算法流程
    当n≤3时,按照贪心规则应直接保留原数字,但由于题目要求必须剪成m>1 段,因此必须剪出一段长度为1的绳子,即返回n - 1。
    当n>3 时,求n/3的整数部分a和余数部分b(即 n = 3a + b),并分为以下三种情况:
    • 当b=0时,直接返回3^a;
    • 当b=1时,要将一个1 + 3转换为 2+2,因此返回 3^(a-1)×4;
    • 当b=2时,返回 3^a×2。
function cutRope(number)
{
    if(number<=3) return number-1
    let a = Math.floor(number/3)
    let b = number%3
    if(b==1) return Math.pow(3,(a-1))*4
    if(b==2) return Math.pow(3,a)*2
    return Math.pow(3,a)
}

你可能感兴趣的:(剑指offer-剪绳子)