剑指Offer面试题14:剪绳子 Java代码实现

剑指Offer 面试题14:剪绳子

原题描述:

面试题14:剪绳子

给你一根长度为n的绳子,请把绳子剪成m段(m,n都是大于1 的整数)。每段绳子长度的可能最大乘积是多少。


分析问题的时候,很容易就可以得出这个问题的递归式:记长度为n的最大乘积为f(n),易知f(n)=max{ f(i)*f(n-i) },其中0<i<n。但是递归求解过程中,有很多子问题会重复求解,效率不高。这种子问题重叠较多的递归式,适合采用动态规划的方式求解。这儿就是使用自底向上的方式求解问题的,采用额外的存储空间,记录子问题的解,后续就可以直接使用,提高时间效率。动态规划实际上就是用空间效率换区时间效率的一种做法。


首先,计算出最基本的几个子问题的解,然后根据递归式向上求解较大问题,重要的是,过程中的解都得记录下来。

	public static int maxProductAfterCutting(int len){
		if(len<2)
			return 0;
		if(len==2)
			return 1;
		if(len==3)
			return 2;
		//存储长度从 0-len 的最大结果
		int[] result=new int[len+1];
		result[0]=0;
		result[1]=1;
		result[2]=2;
		result[3]=3;
		
		//自底向上开始求解
		int max=0;
		for(int i=4;i<=len;i++){
			max=0;
			for(int j=1;j<=i/2;j++){
				int tempResult=result[j]*result[i-j];
				if(max<tempResult)
					max=tempResult;
				result[i]=max;
			}
		}
		max=result[len];
		return max;
	}


这个问题比较特殊,还可以采用贪婪算法得到最优解。Java代码如下:


public static int maxProductWithGreedy(int len){
		if(len<2)
			return 0;
		if(len==2)
			return 1;
		if(len==3)
			return 2;
		//啥也不管,先尽可能减去长度为3的段
		int timeOfThree=len/3;
		
		//判断还剩下多少,再进行处理
		if(len-timeOfThree*3==1)
			timeOfThree-=1;
		int timeOfTwo=(len-timeOfThree*3)/2;
		
		return (int) ((Math.pow(3, timeOfThree))*(Math.pow(2, timeOfTwo)));
	}


贪婪算法效率更高了。不过需要注意的是,不是所有问题都可以采用贪婪策略得到最优解。必须先证明,一个问题可以通过贪婪策略得到最优解,才能采取这种方法。

动态规划以及贪心算法在《算法导论》 16、17章有专门讲解,看完这两章,再看这道面试题算是入门级别的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值