剑指Offer 面试题14 剪绳子

探讨如何将固定长度的绳子剪成多段以获得各段长度乘积的最大值。通过两种算法实现:动态规划和贪婪算法,分别适用于不同场景。
  • 题目
    给你一根长度为n的绳子,请把绳子剪成m段,记每段绳子长度为k[0],k[1]…k[m-1],求k[0]k[1]…k[m-1]的最大值。已知绳子长度n为整数,m>1(至少要剪一刀,不能不剪),k[0],k[1]…k[m-1]均要求为整数。
    例如,绳子长度为8时,把它剪成3-3-2,得到最大乘积18;绳子长度为3时,把它剪成2-1,得到最大乘积2。

  • 实现一 动态规划

    public class CutRope {
    
        /**
         * 得到最大的乘积返回,使用动态规划的方法
         * @param length 待剪绳子的长度
         * @return int
         * */
        public static int theMax(int length) {
            //绳子长度必须大于等于2
            if (length < 2) {
                return 0;
            }
    
            //给出长度较小的绳子剪断以后所得乘积最大的几种情况
            if(length == 2) {
                return 1;
            }
    
            if(length == 3) {
                return 2;
            }
            int[] result = new int[length+1];
            //前三段用来存储长度为i的长度
            //当i>=4时表示把长度为i的绳子剪成若干段之后长度乘积的最大值
            result[0] = 0;
            result[1] = 1;
            result[2] = 2;
            result[3] = 3;
    
            int temp = 0;  //用来暂时保存乘积
            int max = 0;   //存储最大值
            //当长度大于等于4的情况下
            //j代表第一次剪的长度,为了避免重复,i要小于等于长度的一半
            for (int i = 4; i <= length; i++) {
                for (int j = 1; j <= i/2; j++) {
                    temp = result[j] * result[i - j];
                    if(temp > max) {
                        max = temp;
                    }
                }
                result[i] = max;
            }
    
            return result[length];
        }
        public static void main(String[] arg) {
                int max = theMax(10);
                System.out.println("max: " + max);
        }
    }
    
  • 实现二 贪婪算法

    public class CutRopeTwo {
        /**
         * 得到最大的乘积返回,使用贪婪算法
         * @param length 待剪绳子的长度
         * @return int
         * */
        public static int theMax(int length) {
            //length>=5时,尽量取3,当剩余长度等于4时剪成2*2
            int frequency = 0;  //剪成三段的次数
            int remainder = 0;  //被三除取到的余数
            int max = 1;  //保存最大值
    
    
            while (length >= 5) {
                length -= 3;
                frequency++;
                //如果剩余长度为4则不继续进行剪3操作
                if(length == 4) {
                    break;
                }
            }
    
    
            remainder = length;
            if(remainder == 2) {
                max = 2;
            }
    
            if(remainder == 3) {
                max = 3;
            }
    
            if(remainder == 4) {
                max = 4;
            }
    
            for(int i = 0; i < frequency; i++) {
                max = max * 3;
            }
    
            return max;
        }
    
        public static void main(String[] arg) {
            int max = theMax(10);
            System.out.println("max: " + max);
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值