Decode Ways
原题链接Decode Ways
每一个数字和一个字母对应,总共有26个字母,对于每一个或每两个数字,都有可能将其转化成字母,计算有多少中转换形式
以1221为例,所有的转换形式为1->’A’,2->’B’,12->’L’,21->’U’,22->’V’,所有可能的转换结果是
- ABBA ((1)(2)(2)(1))
- ABU ((1)(2)(21))
- AVA ((1)(22)(1))
- LBA ((12)(2)(1))
- LU ((12)(21))
假设给出的数字序列是s[0, 1, …, n],令dp[i - 1]表示s[0, 1, …, i-1]这个数字序列能够表示的所有转化结果个数,那么如何计算dp[i]呢
对于s[0, 1, …, i]这个数字序列的转化结果,可以分成两部分计算
- 由s[0, 1, …, i-1] + s[i]组成,即所有转化形式是s[0, 1, …, i-1]的转换结果后加s[i]表示的字母。如1221可以表示成由122的转换结果后加(1)表示的字母,即集合[ABB, AV, LB] + [A] = [ABBA, AVA, LBA],dp的表示形式为dp[i] += dp[i - 1]
- 由s[0, 1, …, i-2] + s[i-1, i]组成,即所有转化形式是s[0, 1, …, i-2]的转化结果后加由s[i-1, i]表示的字母。如1221可以表示成由12的转换结果后加(21)表示的字母,即集合[AB,L] + [U] = [ABU, LU],dp的表示形式为dp[i] += dp[i - 2]
所以直接动态规划计算即可,dp[i]与dp[i - 1]和dp[i - 2]有关,不过有几个边界条件,尤其注意’0’无法转换成对应字母的情况
- s[i] == ‘0’,s[i]不能表示字母,此时dp[i]与dp[i - 1]无关
- s[i - 1] == ‘0’,s[i-1, i]不能表示字母,此时dp[i]与dp[i - 2]无关
- i == 0 && s[0] != ‘0’,此时dp[0] = 1
- i == 1 && s[0] != ‘0’ && toNumber(s[0, 1]) <= 26,此时dp[1] = 2
代码如下
class Solution {
public:
int numDecodings(string s) {
if(s.empty()) return 0;
vector<int> dp(s.size(), 0