1. 程式人生 > >【LeetCode】91. Decode Ways

【LeetCode】91. Decode Ways

Description:

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation:
 It could be decoded as "AB" (1 2) or "L" (12).

Example 2:

Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

 解題思路:

(1)遞迴解法

題目分析:

如果要用遞迴解法,就需要先找出遞迴公式:

numDecodings[102213] = numDecodings[02213] + numDecodings[2213] 

字串“102213”解碼的方式有兩種:第一種,先解碼子串“1”,再解碼子串“02213”。但是以0開始的子串是無法解析的。第二種,先解碼子串“10”,再解碼子串“2213”。

解碼子串“2213”也有兩種方式:第一種,先解碼子串“2”,再解碼子串“213”。第二種,先解碼子串“22”,再解碼子串“13”。

以此類推。。。

規律顯而易見,類似斐波那契數列。不同的是字串從後往前推出遞推公式。

遞迴公式:

numDecodings[s]= numDecodings[s.substring(1)] + numDecodings[s.substring(2)]

遞迴結束條件:

1. 當前指標所指字元為0

  此時此字元無法解碼,所以遞迴公式中的前者就只能為0,後者也為0。

  例如【023】,substring(1)——【0】|【23】,截掉的【0】不能解析,所以此組合無效。

           substring(2)——【02】|【3】,截掉的【02】不能解析,所以此組合無效。

  所以0數字出現後,解碼數的增量為0。

2. 當前字元的值是有效的(大於0),但是當前字元與右邊字元組合的數字無效(大於26)。

  相當於遞迴公式中的後者為0。

  例如【3212】,substring(1)——【3】|【212】,截掉的【3】能解析,所以其值為【212】的解碼數。

             substring(2)——【32】|【12】,截掉的【32】不能解析,所以此組合無效。

遞迴程式碼:

public class DecodeWays_91 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s = "102213";
		System.out.println(numDecodings(s));
	}
	
    public static int numDecodings(String s) {
    	if(s.isEmpty())
    		return 1;
    	if(s.charAt(0) == '0')
    		return 0;
    	if(s.length() == 1)
    		return 1;
    	int res = numDecodings(s.substring(1));
    	if(s.charAt(0) == '1' || s.charAt(0) == '2' && s.charAt(0+1) - '0' <= 6 )
    		res += numDecodings(s.substring(2));
    	return res;
    }

}

(2)記憶化搜尋解法

先留個標題,有空再來更新。

(3)動態規劃解法

先留個標題,有空再來更新。

Reference: