leetcode : 91. 解码方法
给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。
自上而下,从最大的问题开始,递归 :
12258
/ \
b+2258 m+258
/ \ / \
bc+258 bw+58 mc+58 mz+8
/ \ \ \ \
bcc+58 bcz+8 bwf+8 mcf+8 mzi
/ \ \ \
bccf+8 bczi bwfi mcfi
/
bccfi
有很多子问题被多次计算,比如258被翻译成几种这个子问题就被计算了两次。
用dp来解决,当选中为第i位时,它有两种选择,一、自身1个数,此时dp[i] = dp[i-1];二、和第i-1位构成一个数字,dp += dp[i-1]。也就是说dp[i]起码等于dp[i-1],因为它自身是一个数字;要考虑能不能和i-1构成一个两位数,这个两位数是有限制的,首先要小于25,如果十位是1,个位是几都可以,如果十位是2,个位只能小于6。(leetcode是1~26所以还要判断是否有0,0的话就只能为0)
class Solution {
public:
int numDecodings(string s) {
if(s.empty()) return 0;
vector<int> dp(s.size()+1,0);
dp[0] = 1;
for(int i = 1;i<dp.size();i++){
dp[i] = dp[i-1];
if(i>1 && (s[i-2] == '1' || (s[i-2] == '2' && s[i-1] <'6')))
dp[i] +=dp[i-2];
}
return dp.back();
}
};