【Java】 劍指offer(46) 把數字翻譯成字符串


本文參考自《劍指offer》一書,代碼采用Java語言。

更多:《劍指Offer》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),這就是最終要求的結果。

 

測試算例 

  1.功能測試(1個數字;多個數字)

  2.特殊測試(負數,0,含25、26等)

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.遞歸是自上而下解決問題,如果遇到重復的子問題時,考慮自下而上求解,不用遞歸

  3.g(i,i+1)不僅要判斷<=25,還要判斷>=10,別漏了

 

更多:《劍指Offer》Java實現合集  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM