面试题14:剪绳子
题目:给你一根长度为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(n),时间复杂度为O(n^2)
贪婪算法:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。在剪绳子中,如果绳子的长度大于5,则每次剪出的长度为3的绳子。如果剩下的长度仍然大于5,则接着剪出一段长度为3的绳子,重复这个步骤,直到剩下的长度小于5.时间和空间复杂度都为O(1)。
代码
public class CuttingRope {
public static int maxproduct(int length) {//动态规划
if (length<2) {return 0;}
if (length==2) {return 1;}
if (length==3) {return 2;}
int[] products=new int [length+1];
products[0]=1;
products[1]=1;
products[2]=2;
products[3]=3;
for (int i=4;i<=length;i++) {
int max=0;
for(int j=1;j<=i/2;j++) {
int product=products[j]*products[i-j];
if (max<product) {
max=product;
}
products[i]=max;
}
}
return products[length];
}
public static int maxproduct1(int length) {//贪婪算法
if (length<2) {return 0;}
if (length==2) {return 1;}
if (length==3) {return 2;}
int timesof3=length/3;
if(length-timesof3*3==1) {timesof3 -=1;}
int timesof2=(length-timesof3*3)/2;
int maxproduct1=(int) (Math.pow(3, timesof3)* Math.pow(2, timesof2));
return maxproduct1;
}
public static void main(String[] args) {
int length=10;
int result1 = maxproduct(length);//动态规划的解
int result2 = maxproduct1(length);//贪婪算法的解
System.out.println(result1);
System.out.println(result2);
}
}