本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
題目
給定一個數字,咱們按照以下規則把它翻譯爲字符串:0翻譯成"a",1翻譯成"b",……,11翻譯成"l",……,25翻譯成"z"。一個數字可能有多個翻譯。例如12258有5種不一樣的翻譯,它們分別"bccfi", "bwfi", "bczi", "mcfi" 和"mzi" 。請編程實現一個函數用來計算一個數字有多少種不一樣的翻譯方法。編程
思路
看到題目,很容易想到使用遞歸:用f(i)來表示從第i位開始的不一樣翻譯數目,能夠獲得有:f(i)=f(i+1)+g(i,i+1)*f(i+2)。i和i+1位數字拼起來在10~25範圍內時g(i,i+1)的值爲1,不然爲0。函數
可是存在重複的子問題,因此遞歸併不是最佳方法,咱們從數字的末尾開始計算f(i),自下而上解決問題,就能夠消除重複的子問題了。先算f(len-1),f(len-2),再根據公式f(i)=f(i+1)+g(i,i+1)*f(i+2)往前逐步推導到f(0),這就是最終要求的結果。測試
測試算例 url
1.功能測試(1個數字;多個數字)spa
2.特殊測試(負數,0,含2五、26等).net
Java代碼
//題目:給定一個數字,咱們按照以下規則把它翻譯爲字符串:0翻譯成"a",1翻 //譯成"b",……,11翻譯成"l",……,25翻譯成"z"。一個數字可能有多個翻譯。例 //如12258有5種不一樣的翻譯,它們分別是"bccfi"、"bwfi"、"bczi"、"mcfi"和 //"mzi"。請編程實現一個函數用來計算一個數字有多少種不一樣的翻譯方法。 public class TranslateNumbersToStrings { public int getTranslationCount(int number) { if(number<0) return 0; String sNumber=String.valueOf(number); int len=sNumber.length(); int[] counts=new int[len]; for(int i=len-1;i>=0;i--) { if(i==len-1) { counts[i]=1; }else { counts[i]=counts[i+1]; if(canBeTrans(sNumber,i)) { if(i==len-2) counts[i]+=1; else counts[i]+=counts[i+2]; } } } return counts[0]; } private boolean canBeTrans(String sNumber, int i) { int a=sNumber.charAt(i)-'0'; int b=sNumber.charAt(i+1)-'0'; int convert=a*10+b; if(convert>=10 && convert<=25) return true; return false; } public static void main(String[] args) { TranslateNumbersToStrings demo= new TranslateNumbersToStrings(); System.out.println(demo.getTranslationCount(0)==1); System.out.println(demo.getTranslationCount(10)==2); System.out.println(demo.getTranslationCount(12258)==5); System.out.println(demo.getTranslationCount(-100)==0); } }
收穫
1.遞歸方法,咱們試着用公式描述會比較清晰翻譯
2.遞歸是自上而下解決問題,若是遇到重複的子問題時,考慮自下而上求解,不用遞歸code
3.g(i,i+1)不只要判斷<=25,還要判斷>=10,別漏了