There is only one character 'A'
on the screen of a notepad. You can perform one of two operations on this notepad for each step:
Given an integer n
, return the minimum number of operations to get the character 'A'
exactly n
times on the screen.
Example 1:
Input: n = 3 Output: 3 Explanation: Initially, we have one character 'A'. In step 1, we use Copy All operation. In step 2, we use Paste operation to get 'AA'. In step 3, we use Paste operation to get 'AAA'.
Example 2:
Input: n = 1 Output: 0
Constraints:
1 <= n <= 1000
The problem asks for the minimum number of operations (copy all and paste) to get 'A' exactly n times on a screen, starting with one 'A'.
Several approaches solve this problem:
This solution uses recursion with memoization to avoid redundant calculations.
Approach:
The core idea is that to obtain n
'A's, you might have copied k
'A's and pasted them n/k
times. The minimum steps will be the steps to get k
'A's plus n/k
(the number of pastes). We explore all possible divisors k
of n
. Memoization stores previously computed results for different values of n
to significantly speed up the process.
Time Complexity: O(√n) - The time complexity is dominated by the loop that iterates through divisors of n. In the worst case, we check up to √n divisors (because divisors come in pairs). The memoization ensures that each subproblem (dfs(n/k)
) is solved only once.
Space Complexity: O(n) - The space complexity is due to the memoization table (f
or cache
). In the worst case, the table could store results for all numbers up to n
.
Code (Python):
class Solution:
def minSteps(self, n: int) -> int:
@cache # This is a Python decorator for memoization
def dfs(n):
if n == 1:
return 0
i, ans = 2, n
while i * i <= n:
if n % i == 0:
ans = min(ans, dfs(n // i) + i)
i += 1
return ans
return dfs(n)
Other languages (Java, C++, Go) follow a similar structure, using their respective memoization techniques (arrays or maps).
This approach uses iterative dynamic programming to build a solution from the ground up.
Approach:
We create a dp
array where dp[i]
stores the minimum steps to get i
'A's. We initialize dp[1] = 0
(no steps needed for one 'A'). Then, we iterate from 2 to n
. For each i
, we consider all divisors j
of i
. The minimum steps to get i
'A's will be the minimum of dp[i/j] + j
, where dp[i/j]
is the steps to get i/j
'A's and j
represents the copy-paste operation.
Time Complexity: O(n√n) - The outer loop iterates n
times. The inner loop iterates up to √i times for each i
. The total time complexity becomes roughly O(n√n).
Space Complexity: O(n) - The space complexity is due to the dp
array of size n+1
.
Code (Python):
class Solution:
def minSteps(self, n: int) -> int:
dp = list(range(n + 1))
dp[1] = 0
for i in range(2, n + 1):
j = 2
while j * j <= i:
if i % j == 0:
dp[i] = min(dp[i], dp[i // j] + j)
j += 1
return dp[-1]
Other languages use similar iterative dynamic programming approaches.
This is the most efficient solution, leveraging the mathematical properties of the problem.
Approach:
The problem can be viewed as a prime factorization problem. To obtain n
'A's, we repeatedly copy and paste. The number of steps corresponds to the sum of the prime factors of n
(with multiplicities). For example, if n = 12 = 2^2 * 3
, the minimum steps are 2 + 2 + 3 = 7 (copy 2, paste, copy 2, paste, copy 3, paste).
Time Complexity: O(√n) - The time complexity is dominated by the loop that iterates up to the square root of n to find prime factors.
Space Complexity: O(1) - The algorithm uses a constant amount of extra space.
Code (Java):
class Solution {
public int minSteps(int n) {
int res = 0;
for (int i = 2; n > 1; ++i) {
while (n % i == 0) {
res += i;
n /= i;
}
}
return res;
}
}
Choosing the Best Solution:
Solution 3 (prime factorization) is the most efficient in terms of time complexity, making it the preferred approach for large values of n
. Solutions 1 and 2 are useful for understanding dynamic programming techniques but are less efficient.