1. 程式人生 > >Decode Ways 把字串解碼成數字組合@LeetCode

Decode Ways 把字串解碼成數字組合@LeetCode

做這道題還是有很多收穫的:

1.為了避免麻煩,開陣列時可以開大一些,如int[] ways = new int[len+10];

2. 這道題實際上是和計算要幾步走完臺階的那道題本質是一樣的。同樣要用動態規劃

3. 在拆分時,之前我一直在糾結如何處理0的為題,特別是對於輸入是01,101,1001這樣的數。後來才發現可以用10來判斷,而不用對0去判斷!

具體過程:

要求當前的index為i位置的decode ways,f[i+1]: 

每次對於當前的字元判斷是否屬於1-9(0肯定不行,因為0不在1-26中),如果屬於,那麼當前的字元可以被decode,並且和f[i]組合,f[i+1] += f[i]
然後對於當前字元和前一個字元組成的字串判斷是否屬於10-26,如果屬於,那麼這兩個字元可以被decode,並且和f[i-1]組合,f[i+1] += f[i-1]

我們維護的量res[i]是表示前i個數字有多少種解析的方式,接下來來想想遞迴式,有兩種方式:第一種新加進來的數字不然就是自己比較表示一個字元,那麼解析的方式有res[i-1]種,第二種就是新加進來的數字和前一個數字湊成一個字元,解析的方式有res[i-2]種(因為上一個字元和自己湊成了一個)。當然這裡要判斷前面說的兩種情況能否湊成一個字元,也就是範圍的判斷,如果可以才有對應的解析方式,如果不行,那麼就是0。

package Level3;


/**
 * Decode Ways
 * 
 * A message containing letters from A-Z is being encoded to numbers using the
 * following mapping:
 * 
 * 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given an encoded message containing digits,
 * determine the total number of ways to decode it.
 * 
 * For example, Given encoded message "12", it could be decoded as "AB" (1 2) or
 * "L" (12).
 * 
 * The number of ways decoding "12" is 2.
 * 
 */
public class S91 {

	public static void main(String[] args) {
		String s = "123";
		System.out.println(numDecodings(s));
	}

	public static int numDecodings(String s) {
		int len = s.length();
		if(len == 0){		// 長度為0
			return 0;
		}
		
		int[] ways = new int[len+10];		// 技巧:適當開大一些,這樣可以免去一些特殊情況的麻煩!
		ways[0] = 1;			// 為了兩位數時的情況:ways[2-2] = ways[0]
		ways[1] = s.charAt(0)!='0' ? 1 : 0;	// 在s,index為0的位置
		for(int i=1; i<len; i++){		// 從string的第二位(index=1)開始計算
			int parsed = Integer.parseInt(s.substring(i, i+1));
			if(parsed>=1 && parsed<=9){		// 就當前字元必須滿足1-9
				ways[i+1] += ways[i];
			}
			parsed = Integer.parseInt(s.substring(i-1, i+1));
			if(parsed>=10 && parsed<=26){	// 對於當前字元和前一個字元組成的字串判斷是否屬於10-26
				ways[i+1] += ways[i-1];
			}
		}
		return ways[len];
	}

}