算法学习之把数字翻译成字符串

题目:给定一个数字,我们按照如下规则把它翻译为字符串: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)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章