題目:
給定一個字符串str,str全部由數字字符組成,如果str中某一個或某相鄰兩個字符組成的子串值在1~26之間,則這個子串可以轉換為一個字母。規定“1”轉換為“A”,“2”轉換為“B”,“3”轉換成“C”……“26”轉換為“Z”。寫一個函數,求str有多少種不同的轉換結果,并返回種數。
舉例:
str=“1111”
能轉換出的結果有“AAAA”,“LAA”,“ALA”,"AAL"和“LL”,返回5。
暴力遞歸先定義遞歸函數p(i)(0<=i<=N)。p(i)的含義是str[0..i-1]已經轉換完畢,而str[i..N-1]還沒轉換的情況下,最終合法的轉換種數有多少并返回。特別指出,p(N)表示str[0..N-1](也就是str的整體)都已經轉換完,沒有后序的字符了,那么合法的轉換種數為1,即p(N)=1。比如,str=“111123”,p(4)表示str[0..3](即“1111”)已經轉換完畢,具體結果是什么不重要,反正已經轉換完畢并且不可以變,沒轉換的部分是str[4..5](即“23”),可轉換的為“BC”或“W”只有兩種,所以p(4)=2。p(6)表示str整體已經轉換完畢,所以p(6)=1。那么p(i)如何計算呢?只有以下4中情況。
1、如果i==N,根據上文對P(N)=1的解釋,直接返回1.
2、如果不滿足情況1,又有srt[i]==‘0’,str[0..i-1]已經轉換完畢,而str[i..N-1]此時又以‘0’開頭,str[i..N-1]無論怎樣都不可能合法轉換,所以直接返回0。
3、如果不滿足情況1和情況2,說明str[i]屬于“1~9”,str[i]可以轉化為"A"-“I”,那么p(i)的值一定包含p(i+1)的值,即p(i) = p(i+1)。
4、如果不滿足情況1和情況2,說明str[i]屬于‘1’-‘9’,如果又有str[i..i+1]在“10”~“26”之間,str[i..i+1]可以轉換為‘J’-‘Z’,那么p(i)的值一定也包含p(i+2)的值,即p(i)+=p(i+2).
public int num1(String str){if(str == null || str.equals("")){return 0;}char[] chs = str.toCharArray();return process(chs,0);
}public int process(char[] chs,int i){if(i == chs.length){return 1;}if(chs[i] == '0'){return 0;}int res = process(chs,i+1);if(i+1 < chs.length && (chs[i] - '0') * 10 + chs[i+1] -'0' < 27){res += process(chs,i+2);}return res;
}