题目难度:中等
题目描述:
给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m 、 n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1],...,k[m] 。请问 k[1]*k[2]*...*k[m] 可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18 。- 数据范围: 2 ≤ n ≤ 60
- 进阶:空间复杂度 O(1) ,时间复杂度 O(n)
示例1:
输入:8
返回值:18
说明:8 = 2 +3 +3 , 2*3*3=18
思路1:强行数学解释:
时间复杂度:O(1)
运行时间:3ms 占用内存:584KB
借用一下某位 博主 的图class Solution { public: int cutRope(int number) { if(n <= 2) return 1; if(n == 3) return 2; int n = number; int m = n % 3; if (m == 0) return (int)pow(3, n / 3); else if (m == 1) return (int)pow(3, n / 3 - 1) * 4; else return (int)pow(3, n / 3) * 2; } }
思路二:动态规划:
时间复杂度:O(
)
运行时间:3ms 占用内存:428KB
动态规划问题主要思路:状态表示:怎么去表示问题的状态
- 此问题:dp[i] 表示长度 i 时,可达到的最大乘积
状态计算:怎么计算当前状态
class Solution { private: int dp[70]; public: int cutRope(int number) { if(number <= 3) return number - 1; memset(dp, 0, sizeof dp); dp[1] = 1, dp[2] = 2, dp[3] = 3, dp[4] = 4; for(int i = 5; i <= numbers; ++i) for(int j = 1; j <= i / 2; ++j) dp[i] = max(dp[i], dp[i - j] * j); } }
思路三:贪心算法(推荐)
运行时间:3ms 占用内存:524KB
时间复杂度:O(n),空间复杂度:O(1)
使用贪心思想,不断将绳子分成每段长度为 3 即可让乘积达到最大class Solution { public: int cutRope(int number) { if(number <= 3) return number - 1; int res = 1; while (number > 4) { res *= 3; number -= 3; } return res * number; } }
😘😘😘😘😘😘😘😘😘😘😘