650.2 Keys Keyboar[Medium]
Description
Initially on a notepad only one character ‘A’ is present. You can perform two operations on this notepad for each step:
1.Copy All: You can copy all the characters present on the notepad (partial copy is not allowed).
2.Paste: You can paste the characters which are copied last time.
Given a number n. You have to get exactly n ‘A’ on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n ‘A’.
Example :
Input: 3
Output: 3
Explanation:
Intitally, 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'.
Note:
The n will be in the range [1, 1000].
Solution
题目的意思是,现在给出一个字符“A”,和复制、粘贴两个操作,目标是用最少的操作次数打印出n个A。复制的时候不能选择部分复制,只能将已有的A全部复制。
这题目一看就觉得应该有递推公式,尝试举几个例子。
n = 1,直接返回0;
n = 2,复制、粘贴,返回2;
n = 3,复制、粘贴、粘贴,返回3;
n = 4,有两种选择:复制一次粘贴三次返回4或者利用两个A,即复制一次粘贴一次(AA),再复制一次粘贴一次。返回4;
n = 5,只能复制一次粘贴四次,返回5;
n = 6,有三种做法,相当于(6*1 = 3*2 = 2*3),分别返回6,5,5;
n = 7,只能复制一次粘贴6次,返回7。
发现,通过拆分AAA…字符串,有机会把次数减少。也就是说,要想打印n个A,可以通过先打印(n/i)个A,再复制粘贴这(n/i)个A,实现打印n个A的效果。
递推公式,当i可以被n整除时有效。
f(n) = f(n/i) + i; (i = (n/(n/i));
感觉这道题也有点像,给出一个数字,然后拆分它,拆到基础数字,问拆解需要多少步。比如1024 = 512+512 = 128 + 128 + 128 + 128…….
Complexity analysis
O(logn)
Code
直接写递归比较清晰,也能过;如果超时,可以考虑
用dp数组来存。
class Solution {
public:
int minSteps(int n) {
if (n == 1) return 0;
for (int i = 2; i < n; i++)
if (n % i == 0) return i + minSteps(n / i);
return n;
}
};