面试题14:剪绳子

题目:给你一根长度为n的绳子,把绳子剪成m段(m、n都为整数,n>1,m>1)每段绳子长度为m1,m2,m3,...,mn,求m1*m2*m3*...*mn的最大乘积是多少?例如,绳子长度8,把绳子剪成2,3,3,此时乘积最大为18.

思路一:动态规划,从小往大,从长度为1的绳子开始算最大乘积是多少,假如绳子为1时为f(1)=1,绳子为2时为f(2)=1,绳子为3时为f(3)=2,那么当绳子为4就是max(f(1)*f(3),f(2)*f(2)),以此类推,直到f(n)。

解法一:时间复杂度为O(n^2),空间复杂度为O(n)

package question14;

public class Test1 {
	public static void main(String[] args) {
		System.out.println(maxProductAfterCutting(10));
	}

	private static int maxProductAfterCutting(int length) {
		if(length<2)
			return 0;
		if(length==2)
			return 1;
		if(length==3)
			return 2;
		int[] product=new int[length+1];
		//绳长为1,2,3
		product[1]=1;
		product[2]=2;
		product[3]=3;
		int max=0;
		//绳长大于4后开始计算
		for(int i=4;i<=length;i++){
			max=0;
			for(int j=1;j<=i/2;j++){
				int temp=product[j]*product[i-j];
				if(max<temp)
					max=temp;
			}
			product[i]=max;
		}
		return product[length];
	}
}

 

思路二:贪婪算法,通过举例分析可以发现,4分为2 2,5分为2 3,6分为3 3,7分为2 2 3,8分为2 3 3,9分为3 3 3,10分为2 2 3 3,当n>=5时,绳子应该尽量分成长度为3的,但到最后不能剩下长度为1,比如10分成2 2 3 3,乘积为36,分成1 3 3 3,乘积为27,所以一开始分绳子就直接拼长度为3的,不够就拼长度为2.

解法二:时间复杂度为O(1),空间复杂度为O(1)

public class Test2 {
	public static void main(String[] args) {
		System.out.println(maxProductAfterCutting(10));
	}

	private static int maxProductAfterCutting(int length) {
		if(length<2)
			return 0;
		if(length==2)
			return 1;
		if(length==3)
			return 2;
		int num3Count=length/3;
		if(length-3*num3Count==1){
			num3Count-=1;
		}
		int num2Count=(length-3*num3Count)/2;
		int max=3*num3Count+2*num2Count;
		return max;
	}
}	

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值