当前位置: 首页 > news >正文

剑指offer-67、剪绳⼦

题目描述

给你⼀根⻓度为n 的绳⼦,请把绳⼦剪成整数⻓的m 段( m 、n 都是整数, n>1 并 且m>1 , m<=n ),每段绳⼦的⻓度记为k[1],...,k[m]。请问k[1]x...xk[m] 可能的最⼤乘积是多少?例如,当绳⼦的⻓度是8 时,我们把它剪成⻓度分别为2 、3 、3 的三段,此时得到的最⼤乘积是18`。

输⼊描述:输⼊⼀个数n,意义⻅题⾯。(2 <= n <= 60)

返回值描述:输出答案。

示例1
输⼊:8
返回值:18

思路及解答

备忘录

本题的解答思路就是每个⻓度的绳⼦,要么最⻓的情况是不剪开(⻓度是本身),要么⻓度是剪开两段的乘积。因此每个⻓度 length 都需要遍历两个相加之后等于 length 的乘积,取最⼤值。

初始化值⻓度为 1 的值为 1 ,从⻓度为 2 开始,每⼀种⻓度都需要遍历两个⼦⻓度的乘积。

显然,为了避免多次重复计算,可以写个备忘录

java

public class Solution { public int cutRope(int target) { if (target <= 1) { return target; } int[] nums = new int[target + 1]; nums[1] = 1; nums[0] = 1; for (int i = 2; i <= target; i++) { int max = i; for(int j=0;j<=i/2;j++){ int temp = nums[j] * nums[i-j]; if(temp > max){ max = temp; } } nums[i]=max; } return nums[target]; } }

动态规划

⽤动态规划的思维来做,假设绳⼦⻓度为 n 的 最⼤的⻓度为 f(n) ,那你说 f(n) 怎么计算得来呢?

  1. f(n) 可能是 n(不切分)
  2. 也可能是 f(n-1) 和 f(1) 的乘积
  3. 也可能是 f(n-2) 和 f(2) 的乘积
  4. ......

那么也就是想要求 f( n ) 我们必须先把 f(n-1) , f(n-2) ...之类的前⾯的值先求出来, f(1)=1 这是初始化值。

java

public class Solution { public int cutRope(int target) { int[] dp = new int[target + 1]; dp[1] = 1; for (int i = 2; i <= target; i++) { for (int j = 1; j < i; j++) { dp[i] = Math.max(dp[i], (Math.max(j, dp[j])) * (Math.max(i - j, dp[i - j]))); } } return dp[target]; } }
  • 时间复杂度:O(n²),外层循环n-3次,内层循环i/2次
  • 空间复杂度:O(n),需要dp数组存储中间结果

贪心算法(最优解)

基于数学推导的贪心策略,优先剪出长度为3的段。当n≥5时,优先剪出长度为3的段;剩余4时剪成2×2

为什么选择3?

  1. 数学证明:当n ≥ 5时,3(n-3) ≥ 2(n-2) > n
  2. 接近自然底数e:最优分段长度应接近e ≈ 2.718,3是最接近的整数
  3. 4的特殊处理:2×2 > 3×1,所以剩余4时剪成2×2而不是3×1

java

public class Solution { public int cutRope(int n) { // 特殊情况处理 if (n <= 3) return n - 1; // 计算可以剪出多少段长度为3的绳子 int countOf3 = n / 3; // 处理剩余部分:当剩余长度为1时,调整策略 if (n - countOf3 * 3 == 1) { countOf3--; // 减少一段3,与剩余的1组成4 } // 计算剩余部分能剪出多少段长度为2的绳子 int countOf2 = (n - countOf3 * 3) / 2; // 计算结果:3的countOf3次方 × 2的countOf2次方 return (int)(Math.pow(3, countOf3)) * (int)(Math.pow(2, countOf2)); } }
  • 时间复杂度:O(1),只有常数次操作
  • 空间复杂度:O(1),只使用固定变量

数学公式法(理论最优)

根据n除以3的余数直接套用公式

java

public class Solution { public int cutRope(int n) { if (n <= 3) return n - 1; int countOf3 = n / 3; int remainder = n % 3; // 根据余数直接返回结果 if (remainder == 0) { return (int) Math.pow(3, countOf3); } else if (remainder == 1) { return (int) Math.pow(3, countOf3 - 1) * 4; } else { // remainder == 2 return (int) Math.pow(3, countOf3) * 2; } } }
http://www.jsqmd.com/news/1101097/

相关文章:

  • 一文搞懂 Function Calling、MCP、Tool、Skill:大模型能力扩展技术栈深度对比
  • 300 行源码,2KB 体积:quicklink 的预加载调度设计,比你的 ‘防抖+节流’ 高出一个维度
  • 如何用Kazumi打造你的专属番剧库:插件安装与配置完全指南
  • 手把手教你用EmEditor和dtc工具拆解Linux设备树dtb文件(附二进制查看技巧)
  • Inpaint-Web:本地离线AI图片4倍超分与智能去水印实战指南
  • 告别成本超支、回款停滞:易趋助力交付类项目实现业财一体精细化经营
  • 第五难:MongoDB到PostgreSQL的类型转换
  • ESXi 免费版有官方技术支持吗?订阅授权支持规则说明
  • SENAITE LIMS:现代化实验室信息管理系统的架构解析与实施指南
  • 别再死记硬背公式了!用Python可视化理解拉梅系数与正交坐标系
  • 别再傻傻分不清!一文搞懂Chiplet、SiP、SoC和MCM到底有啥区别(附AMD实例)
  • 灯塔工厂的AI底座:从单点智能到工厂核心操作系统的演进
  • 3步解锁百度网盘30倍下载速度:从限速到飞驰的实战指南
  • 别再问‘服务器能扛多少QPS’了!从4核8G的压测数据,聊聊真实业务场景下的性能估算
  • 企业级考研互助交流平台管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • SAP采购申请报表开发避坑指南:EBAN/EBKN表关联与审批状态判断的实战细节
  • 从Wireshark抓包看CURLOPT_POSTFIELDSIZE:为什么你设置的包大小和抓到的TCP包不一样?
  • 连享会课程分享
  • 3个技巧快速掌握多显示器亮度调节神器
  • 112G AI 服务器高速线束自动化生产线定制指南 非标线束整线方案参考
  • Axure RP中文界面终极指南:3分钟搞定完整汉化教程
  • 终极指南:使用QrazyBox免费修复损坏二维码
  • 别再混淆了!嵌入式开发中的TCM、ITCM、DTCM到底怎么用?(以Cortex-M为例)
  • 告别Anchor框!用HRNet+CenterNet搭建YOLC,实测VisDrone小目标检测AP提升5%
  • GSAP 高级动画技巧:构建丝滑流畅的页面动效编排
  • 多通道高速采集系统的“最后一步”:零拷贝DMA设计——避免CPU卡死、数据错位的工程实践
  • 空洞骑士模组管理器Scarab:跨平台一键安装的智能解决方案
  • 别再直接积分了!用MPU6050陀螺仪数据算姿态角,为什么你的无人机飞机会‘乱飘’?
  • AI合规高阶:AI跨境合规的难点与解决方案
  • 逆向实战:用Python一步步还原新版a_bogus算法(附完整日志分析)