算法學習之把數字翻譯成字符串

題目:給定一個數字,我們按照如下規則把它翻譯爲字符串:0翻譯成“a”,1翻譯成“b”,……,11翻譯成“l”,……,25翻譯成“z”。一個數字可能有多個翻譯。例如,12258有5種不同的翻譯,分別是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”。請編程實現一個函數,用來計算一個數字有多少種不同的翻譯方法。

思路:到最後感覺就是一道找規律的題目。使用動態規劃解題。。。

先看一張圖:

使用上述遞歸方式的話,會有很多重複的子運算,入兩邊都會子弟規258這個數字。

那麼正題就來了,使用動態規劃優化下就歐了。

我們通過找規律發現:f(i) = f(i+1)+g(1+1,i+2)*f(i+2),代表從當前位置開始至最後一位,存在幾種組合,g(i+!,i+2)代表第i+1與i+2個數拼接到一起是不是在10~25這個範圍內。先別蒙我舉個例子解釋下就感覺很簡單了。

就拿題中給的數來說12258:這裏的i代表索引值index

f(4) = 1種    8->i

f(3) = 1種    58->fi

f(2) = 2種    258->cfi/zi

f(1) = 3種   2258->wfi/ccfi/czi

f(0) = 5種  12258->mzi/bwfi/bccfi/mcfi/bczi

好了,從上邊找到的規律就是f(i) = f(i+1)+g(1+1,i+2)*f(i+2)了

 public int getNemberCount(int number){
        if(number<0) return 0;
        String numberS = String.valueOf(number);
        int length = numberS.length();
        int [] counts= new int[length];
        for (int i=length-1;i>=0;i--){
            if(i==length-1) {
                counts[i] = 1;
            }else {
                counts[i] =counts[i+1];
                if(isInTheRange(i,numberS)) { // 判斷是否在範圍內10~25
                   if(i+2==length) { // 這種條件下最右兩位爲兩種情況,所以單獨處理
                       counts[i]+=1;
                   }else {
                       counts[i]+=counts[i+2];
                   }
                }
            }
        }
        return counts[0];

    }

    private boolean isInTheRange(int i, String num) {
        String numberS = num.substring(i, i+2);
        Integer number = Integer.valueOf(numberS);
        return number >= 10 && number <= 25;
    }
  • 時間複雜度:O(n)。
  • 空間複雜度:O(n)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章