一、题目描述:91. 解码方法(中等)
一条包含字母 A-Z 的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。示例 1:
输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。
示例 2:输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-ways
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
动态规划
动态方程,dp[i] = dp[i-1] + dp[i-2],成立的条件是1)s[i] 在1~9之间,2)s[i-1~i]在10~26之间。
如果条件1不成立,条件2成立,则,dp[i] = dp[i-2]
如果条件1成立,条件2不成立,则,dp[i] = dp[i-1]
如果两个条件都不成立则,dp[i] = 0。
使用两个变量分别保存dp[[i-1],dp[i-2]则空间复杂度可以降为O(1)
三、代码
class Solution {
public:
int numDecodings(string s) {
vector<int> dp(s.size(),0);
if(s.size() == 0)
return 0;
dp[0] = 1;
if(s[0] =='0')
{
dp[0] = 0;
}
if(s.size() == 1)
return dp[0];
if(s[0] != '0'&& atoi(s.substr(0,2).c_str()) <= 26 && atoi(s.substr(0,2).c_str()) >0)
{
if(s[1] != '0')
dp[1] = 1 + dp[0];
else
dp[1] = dp[0];
}
else if(s[1] == '0')
{
dp[1] = 0;
}
else
{
dp[1] = dp[0];
}
for(int i = 2; i < s.size(); i ++)
{
if(s[i-1] != '0' && atoi(s.substr(i-1,2).c_str()) <= 26 && atoi(s.substr(i-1,2).c_str())>0)
{
if(s[i] == '0')
dp[i] = dp[i-2];
else
{
dp[i] = dp[i-1] + dp[i-2];
}
}
else
{
if(s[i] == '0' && s[i-1] == '0')
dp[i] = 0;
else if(s[i] == '0')
{
dp[i] = 0;
}
else
{
dp[i] = dp[i-1];
}
}
}
//print(dp);
return dp[s.size()-1];
}
void print(vector<int> & dp)
{
for(int i = 0;i < dp.size(); i++)
cout<<dp[i]<<",";
cout<<endl;
}
};