【LeetCode】650. 只有兩個鍵的鍵盤

只有兩個鍵的鍵盤

最初在一個記事本上只有一個字符 'A'。你每次能夠對這個記事本進行兩種操做:
1.Copy All (複製所有) : 你能夠複製這個記事本中的全部字符(部分的複製是不容許的)。
2.Paste (粘貼) : 你能夠粘貼你上一次複製的字符。
給定一個數字 n 。你須要使用最少的操做次數,在記事本中打印出剛好 n 個 'A'。輸出可以打印出 n 個 'A' 的最少操做次數。
示例 1:java

輸入: 3
輸出: 3
解釋:
最初, 咱們只有一個字符 'A'。
第 1 步, 咱們使用 Copy All 操做。
第 2 步, 咱們使用 Paste 操做來得到 'AA'。
第 3 步, 咱們使用 Paste 操做來得到 'AAA'。code

說明:
1.n 的取值範圍是 [1, 1000] 。遞歸


分析

若是每次Paste 'A',顯然操做次數就是n,那麼怎麼減小次數呢?這裏分爲兩種狀況:
1.n爲質數,不管剪切板裏有多少個‘A'(除了1個'A'的狀況),最終都沒法獲得n個'A',因此最少操做次數爲n;
2.n爲合數,獲得最少操做次數的狀況發生在已經有(n / i)個'A',其中i爲最小的能整除n的數(i大於1),說明只要操做i次就能獲得n個'A'。leetcode

暴力遞歸

class Solution {
    public int minSteps(int n) {
        
        if(n == 1) return 0;
        int i = 2;
        while(n % i != 0) i++;
        if(i == n) return n;
        return i + minSteps(n / i);
    }
}

遞歸轉迭代

class Solution {
    public int minSteps(int n) {
        
        int res = 0;
        for (int i = 2; i <= n; i++) {
            while (n % i == 0) {
                res += i;
                n /= i;
            }
        }
        return res;
    }
}

動態規劃

class Solution {
    public int minSteps(int n) {
        
        int[] dp = new int[n + 1];
        for(int i = 2; i <= n; i++){
            dp[i] = i;
            for(int j = 2; j < i; j++){
                if(i % j == 0){
                    dp[i] = Math.min(dp[i], dp[i / j] + j);
                }
            }
        }
        return dp[n];
    }
}
相關文章
相關標籤/搜索