关于2 Keys Keyboard递归算法时间复杂度的技术咨询
分析2 Keys Keyboard递归解法的时间复杂度及最坏情况
首先,先明确下问题背景,方便回顾:
初始记事本上只有1个'A',每次可以执行两种操作:Copy All(复制当前所有字符)、Paste(粘贴上次复制的内容)。给定n,求得到恰好n个'A'的最少操作步数。
你的递归解法逻辑很直观:通过递归枚举每一步的两种选择(直接粘贴上次复制的内容,或者粘贴后立即复制新的内容),取能到达目标的最小步数。接下来我们拆解时间复杂度和最坏情况:
递归解法的核心逻辑
你的recursiveDriver函数每一步会生成两个分支:
- 仅粘贴:步数+1,当前字符数增加
previousCopy,复制内容保持不变 - 粘贴后复制:步数+2,当前字符数增加
previousCopy,复制内容更新为新的字符数
当字符数超过目标时返回无穷大(代表该路径无效),等于目标时返回当前步数,最终取两个分支的最小值。
时间复杂度与最坏情况分析
你最初认为时间复杂度是O(2n),这个是对最坏情况的上界,但要明确:**最坏情况对应的n并不是质数,而是形如2k的2的幂次(比如2、4、8、16...)**。
为什么是2的幂次?原因很简单:
- 对于质数n,比如n=5,粘贴后复制的分支会很快超过目标(比如从2个'A'复制后,粘贴一次就到4个,再粘贴就到6个超过5),所以大部分分支都是无效的,递归树的规模其实很小,远达不到O(2^n)。
- 而对于2的幂次n,比如n=8,每一步的两个分支都是有效的:
- 你可以选择一步步粘贴(1→2→3→4→5→6→7→8)
- 也可以选择粘贴后复制翻倍(1→2→4→8),或者混合两种操作(比如1→2→3→4→8)
每个中间状态都能生成两个有效的子分支,递归树会呈指数级增长,最终接近O(2^n)的时间复杂度。
另外要注意,你的递归没有做记忆化,会存在大量重复计算(比如不同路径到达同一个(currCount, previousCopy)状态时,会重复递归),这进一步放大了时间开销。如果加上记忆化(比如用哈希表缓存每个状态的最小步数),时间复杂度可以降到O(n²),因为状态总数是O(n²)(currCount从1到n,previousCopy最多等于currCount)。
内容的提问来源于stack exchange,提问作者Nithin
相关产品推荐
相关产品推荐

