剑指 Offer 14- I. 剪绳子
思路#
方法一:动态规划#
从题目中可以看出,有最优子结构,可以联想到动态规划,其递归树如下:
可以看出,具有很多重叠子问题。
1 /*记忆化搜索代码*/ 2 class Solution { 3 private: 4 // 记忆化搜索,自顶向下 5 // memo[n]表示分割n获得的乘积最大值 6 vector<int> memo; 7 int max3(int a, int b, int c) { 8 return max(a, max(b,c)); 9 } 10 int breakInteger(int n) { 11 if(n == 1) 12 return 1; 13 14 if(memo[n] != -1) 15 return memo[n]; 16 17 int res = -1; 18 for(int i = 1; i < n; ++i) { 19 res = max3(res, i*(n-i), i * breakInteger(n-i)); 20 } 21 memo[n] = res; 22 return memo[n]; 23 24 } 25 public: 26 int integerBreak(int n) { 27 memo = vector<int>(n+1, -1); 28 return breakInteger(n); 29 } 30 }; 31 32 /*动态规划代码*/ 33 class Solution { 34 private: 35 // 动态规划,自底向上 36 // 求三个数中的最大值 37 int max3(int a, int b, int c) { 38 return max(a, max(b,c)); 39 } 40 41 public: 42 int integerBreak(int n) { 43 vector<int> memo(n+1, -1); 44 // memo[i]表示分割i获得的乘积最大值 45 // 题目中说了n>=2,所以这里不能写memo[3]=2,否则当输入的n是2时会越界 46 memo[1] = 1; 47 memo[2] = 1; 48 for(int i = 3; i <= n; ++i) { 49 for(int j = 1; j < i; ++j) { 50 memo[i] = max3(memo[i], j*(i-j), j*memo[i-j]); 51 } 52 } 53 return memo[n]; 54 } 55 };
复杂度分析#
记忆化搜索:
时间复杂度:O(n2),因为breakInteger递归函数中有一个n次循环,每个memo[i]的值只会被计算一次,不会重复递归计算相同的memo[i] (因为相同的直接返回了),所以时间复杂度为O(n2)
空间复杂度:O(n)
动态规划:
时间复杂度:O(n2)
空间复杂度:O(n)
方法二:数学#
以下证明来自:《剑指offer(第2版)》,面试题14- I. 剪绳子(数学推导 / 贪心思想,清晰图解)
更详细的数学证明见:力扣官方题解 - 整数拆分
1 class Solution { 2 public: 3 int cuttingRope(int n) { 4 if(n <= 3) 5 return n-1; 6 int res = 1; 7 while(n > 4) 8 { 9 n = n - 3; //尽可能地多剪长度为3的绳子 10 res = res * 3; 11 } 12 return res * n; 13 } 14 };
参考#
分类:
剑指Offer(第2版)
标签:
动态规划
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南