By Jalan
知识工具需求
DP
题解
DP
思路
从左到右进行解码.
举个例子
设串为1112
- 串只有1 目前处理1 没有前字符,不会有多解,dp[0]=1 只有A一个解.
- 串有11 目前处理1 有前字符1. 有多解AA ,K 其中单字符解永远不增加解.所有的多解都是由于组合解产生的.dp[1]=2
- 串有111 目前处理1 有前字符1 有解AAA KA AK 可以发现,单解的A不增加解的数量,和前字符构成多解的K才会增加解的数量,且增加量是dp[i-2] 所以dp[i]=dp[2]+dp[1]=3
- 串有1112 目前处理2 有前字符1 有解 AAAB KAB AKB 和AAL KL 单解B不增加解的数量,只有B和前A组成L时增加解的数量.增量是dp[2]=2;dp[4]=dp[3]+dp[2]=5
注意 ,有多解的条件是复杂的,特别是请注意本字符是0的情况,这种情况不允许上一个字符是多解。
按照这个逻辑写即可
预期时间复杂度
O(n)
编写用时
5分钟代码 写了15分钟思路.
代码
CPP
class Solution {
public:
int numDecodings(string s) {
if(s.at(0)=='0'){
return 0;
}
vector<int> dp(s.size()+1,0);
dp[0]=1;
dp[1]=1;
bool ableToSolve=true;
for(int i=2;i<dp.size();++i){
auto strIndex=i-1;
if(s[strIndex]=='0'){
if(s[strIndex-1]=='1'||s[strIndex-1]=='2'){
//如果是0的话,前字符不能被用于多解
dp[i-1]=dp[i-2];
dp[i]=dp[i-1];
continue;
}else{
ableToSolve=false;
break;
}
}else if((s[strIndex-1]=='1'&&(s[strIndex]>='1'&&s[strIndex]<='9'))||(s[strIndex-1]=='2'&&(s[strIndex]>='1'&&s[strIndex]<='6'))){
//有多解的判断条件 前字符是1 本字符是[1,9],前字符是2本字符是[1,7]
dp[i]=dp[i-1]+dp[i-2];
continue;
}else{
dp[i]=dp[i-1];
continue;
}
}
return ableToSolve?dp[dp.size()-1]:0;
}
};