leetcode_650 只有两个键的键盘

128 阅读2分钟

要求

最初记事本上只有一个字符 'A' 。你每次可以对这个记事本进行两种操作:

  • Copy All(复制全部):复制这个记事本中的所有字符(不允许仅复制部分字符)。
  • Paste(粘贴):粘贴 上一次 复制的字符。 给你一个数字 n ,你需要使用最少的操作次数,在记事本上输出 恰好 n 个 'A' 。返回能够打印出 n 个 'A' 的最少操作次数。

示例 1:

输入:3
输出:3
解释:
最初, 只有一个字符 'A'。
第 1 步, 使用 Copy All 操作。
第 2 步, 使用 Paste 操作来获得 'AA'。
第 3 步, 使用 Paste 操作来获得 'AAA'

示例 2:

输入:n = 1
输出:0

提示:

  • 1 <= n <= 1000

核心代码

class Solution:
    def minSteps(self, n: int) -> int:
        if n == 1:
            return 0
        for i in range(2,n):
            if n % i == 0:
                return self.minSteps(n // i) + i
        return n

image.png

解题思路:递归
我们先分析递归的方法,递归的思想是由上向下。

举个例子:当 n = 36 的时候。

36 = 18 * 2 = 3 * 3 * 2 * 2

如果我们想获得 36 个相同的A,可以先获得 18 个'A',然后复制 1 次,粘贴 1 次,于是就有了 36 个'A'。这就是 36 = 18 * 2 的含义。然后再思考怎么得到 18 个'A',这就是递归。

当起始只有一个'A'的情况下,一种得到36个'A'的方案为:

复制 1 次,粘贴 2 次,得到 'AAA' 在上面的基础上,复制 1 次,粘贴 2 次,得到 'AAAAAAAAA' 在上面的基础上,复制 1 次,粘贴 1 次,得到 18 个 'A' 在上面的基础上,复制 1 次,粘贴 1 次,得到 36 个 'A' 因为复制和粘贴都算一次操作,所以上面得到了 3 * 3 * 2 * 2 = 36 个'A'。

我们可以得出结论:

如果 n 是素数的话,我们只能通过复制 1 次A,然后粘贴 n - 1 次的方式才能得到 n 个A。总的操作了 n 次。 如果 n = i * j 的话,最快得到 n 的方式是先得到 i ,复制 1 次,然后再粘贴 j - 1 次(因为原本就有1次,所以这里是j - 1次),总的就有了 n 个A。总的操作了 minSteps(i) + 1 + j - 1 = minSteps(i) + j = minSteps(i) + n / i 次。 于是就有了递归的解法。该解法是,先让 i 从 2 开始遍历找到 n - 1,判断 i 是不是 n 的因子,如果 i 是 n 的因子,那么总的需要操作 minSteps(i) + n / i次。如果从 2 到 n - 1 没有 n 的因子,那么 n 是个素数,必须操作 n 次。