题目描述
把一根绳子剪成多段,并且使得每段的长度乘积最大。
贪心算法
//贪心算法 时间复杂度O(1) 空间复杂度O(1)
//解题思路
//当 n >= 5 时,可以证明 2(n - 2) > n 并且3(n - 3) > n,所以说当绳子剩下的长度大于或者等于5的时候
//我们就把他剪成长度为3或者为2的绳子段。同时,3(n - 3) >= 2(n - 2)
//所以我们应该尽可能去多剪长度为3的绳子段。
//但是当n = 5 时 1 * 3 < 2 * 2 所以当绳子的长度为4的时候没必要剪,但是题目要求剪一刀
//所以剪为 2 2。
public int maxProductAfterCutting2(int n)
{
if (n < 2)
return 0;
if (n == 2)
return 1;
if (n == 3)
return 2;
if (n == 4)
return 4;
//计算给的数中个有多少个3
int countOf3 = n / 3;
//如果有4的话,就把这个3归还, 变为3 * 2 * 2。
// 因为3 * 3 * 1 < 3 * 2 * 2
if (n - countOf3 * 3 == 1)
countOf3--;
int countOf2 = (n - countOf3 * 3) / 2;
return (int) ((Math.pow(3, countOf3)) * (Math.pow(2, countOf2)));
}
动态规划
//动态规划 时间复杂度 O(n * n),空间复杂度 O(n)
public int maxProductAfterCutting(int len)
{
if (len < 1)
return 0;
int[] product = new int[len + 1];
product[1] = 0;
for (int i = 2; i <= len; i++)
{
for (int j = 1; j < 2; j++)
{
//更新product[i] //找出(i - j)*j的最大值
product[i] = Math.max(product[i], Math.max((i - j) * j, product[j] * (i - j)));
}
}
/* 或者这样写
for (int i = 2; i <= len; i ++)
{
int max = 0;
for (int j = 1; j < 2; j ++)
{
if(max < (i - j) * j)
max = (i - j) * j;
}
product[i] = max;
}
*/
return product[len];
}