原题链接:91. 解码方法
solution:
动态规划:
状态表示:dp[i]表示字符串s[0 ~ i - 1]的解码方法数
转移方程: 类似于爬楼梯的dp[i] = dp[i - 1] + dp[i - 2],只不过加了约束条件
class Solution {
public:
int numDecodings(string s) {
int n = s.length();
if(n == 0) return 0;
if(s[0] == '0') return 0;
vector<int> dp(n + 1, 0); //dp[i]表示字符串s[0 ~i - 1]映射的方法数
dp[0] = 1;
for(int i = 0; i < n; ++i){
dp[i+1] = s[i] == '0' ? 0 : dp[i];
if(i > 0 && (s[i-1] == '1' || (s[i-1] == '2' && s[i] <= '6'))){
dp[i+1] += dp[i-1];
}
}
return dp[n];
}
};
深度优先搜索+记忆化
class Solution {
public:
vector<int> sta;
int numDecodings(string s) {
if(s.size() == 0) return 0;
sta = vector<int> (s.size(), -1);
int ans = dfs(s, 0);
return ans;
}
//dfs返回以start为起点的方法数
int dfs(string &s,int start) {
//终止条件
if(start == s.size()) return 1;
//剪枝,没有0开始的映射
if(s[start] == '0') return 0;
if(sta[start] != -1) return sta[start]; //记忆化搜索
int ans = dfs(s, start + 1); //由于start位不为0,所以移动1位是有效的
if(s.size() - start >= 2) { //剩余位数大于等于2
if(s[start] == '1' || s[start] == '2' && s[start + 1] <= '6')
ans += dfs(s, start + 2);
}
sta[start] = ans; //记忆化
return ans;
}
};