91. 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.
【题目分析】
给定一种字符到数字的编码方式,求出一个指定数字序列有多少种解码方式。
【思路】
用动态规划的思想来解决。
设定状态为:f[i]
表示s
从0
开始,长度为i
的子串的解码方式数量,于是我们最终要求的答案便是f[n]
。
那么如何求解f[i]
呢?这个很简单,枚举最后一个字母对应1位还是2位,将f转化为规模更小的子问题。
- 设
f[i] = 0
- 枚举最后一个字母对应1位(要求
s[i - 1] != '0'
),那么有f[i] += f[i-1]
; - 枚举最后一个字母对应2位(要求
i > 1
且s[i - 2]
和s[i - 1]
组成的字符串在"10"~"26"
的范围内),那么有f[i] += f[i - 2]
;
也就是说,我们可以通过f[i - 1]和f[i - 2]计算出f[i]来,这就是我们的状态和转移方程。
在具体实现中,我们可以按照i从1到n的顺序,依次计算出所有的f[i]。
【java代码】
1 public class Solution { 2 public int numDecodings(String s) { 3 if(s.length() == 0) return 0; 4 int[] f = new int[s.length()+1]; 5 f[0] = 1; 6 7 for(int i = 1; i < f.length; i++) { 8 if(s.charAt(i-1) != '0') { 9 f[i] += f[i-1]; 10 } 11 if(i > 1 && s.substring(i-2, i).compareTo("10") >=0 && s.substring(i-2, i).compareTo("26") <= 0) { 12 f[i] += f[i-2]; 13 } 14 } 15 16 return f[s.length()]; 17 } 18 }