剑指offer js算法练习之动态规划与贪婪算法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37473645/article/details/85156640

剪绳子

        给定一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]* k[1] * … *k[m]可能的最大乘积是多少?

举例

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

分析

        解决这个问题有两个不同的方法解决这个问题。第一种是动态规划,需要O(n2)时间和O(n)空间。第二种是贪婪算法,只需要O(1)时间和空间。

一、动态规划

        如果面试题是求一个问题的最优解(通常是求最大值和最小值),而且该问题能够分解成若干个子问题,并且子问题之间还有重叠的更小的子问题,就可以考虑用动态规划来解决这个问题。

function maxProductAfterCutting_solution1(length){
    if(length<2){
        return 0;
    }
    if(length==2){
        return 1;
    }
    if(length==3{
        return 2;
    }
    var products=new Array();
    products[0]=0;
    products[1]=1;
    products[2]=2;
    products[3]=3;
    var max=0;
    for(var i=4;i<=length;i++){
        max=0;
        for(var j=0;j<=Math.floor(i/2);j++){
            var product=products[j]*products[i];
            if(max<product){
                max=product;
            }
            products[i]=max;
        }
    }
    max=products[length];
    detele products;
    return max;
}

 

        上述代码中,子问题从长度为4的绳子开始最优解存在数组products里面,products[0]=0到products[3]=3分别代表的是长度为0,1,2,3的绳子的长度。当数组中第i个元素表示把长度为i的绳子剪成若干段之后各段长度乘积的最大值,即f(i)。我们注意到代码中的第一个for循环变量i是顺序递增的,这意味着计算顺序是自下而上。因此在求f(i)之前,对于每一个j(0<i<j)而言,f(j)都已经求解出来了,并且结果保存在projects[j]里。为了求解f(i),我们需要求出所有可能的f(j)xf(i-j)并比较得出它们的最大值。这就是代码中第二个for循环的功能。

二、贪婪算法

        贪婪算法和动态规划不一样。当我们应用贪婪算法解决问题的时候,每一步都可以做出一个贪婪的选择,基于这个选择,我们确定能够得到最优解。

猜你喜欢

转载自blog.csdn.net/qq_37473645/article/details/85156640
今日推荐