解法1:动态规划
思想:
dp[n]代表长度为n的绳子剪完后长度乘积的最大值,长度123不剪比剪要更大,所以不剪,4开始就肯定是剪后>=剪前,所以dp[i] = max(dp[i], dp[j] * dp[i - j]);
复杂度
时间复杂度:O(n^2),两次循环
空间复杂度:dp数组占据O(n)空间
代码
class Solution {
public:
int cuttingRope(int n) {
//n <= 3时,数字要求至少分为两部分,实际结果的最大值为n - 1
if(n <= 3)
return n - 1;
vector<int>dp(n + 1, 0);
//到dp中时,不一定要拆为两部分,所以为1、2、3,从4开始就是拆开更大,所以可以算出来
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
for(int i = 4; i <= n; i++)
for(int j = 1; j <= i / 2; j++){
dp[i] = max(dp[i], dp[j] * dp[i - j]);
}
return dp[n];
}
};
解法2:贪心
思想:
任何大于1的数都能用2a + 3b表示,即由2和3相加组成
n >= 5时,3(n - 3) >= 2(n - 2) > n,剩下的绳子长度大于或者等于5的时候,就把他剪成长度为3的绳子段。
n为4时,剪成2 * 2最大,为4
n <= 3时,为n - 1
复杂度:
时间O(1),空间O(1)
class Solution {
public:
int cuttingRope(int n) {
if(n <= 3)
return n - 1;
int res = 1;
while(n > 4){
n = n - 3; //尽可能多剪长度为3的绳子
res = res * 3;
}
return res * n;
}
};