题目:
Decode Ways
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
用动态规划,分两种情况讨论:两个字符连在一起,以及不连在一起。
class Solution {
public:
int numDecodings(string s) {
//若为空
if(s.empty())
return 0;
//开头为0
if(s[0]=='0')
return 0;
//长度为1且开头不为0
if(s.size()==1)
return 1;
//f_lian的第i位是指:字符串s[i:]中,s[i]和s[i+1]连在一起的解码方式
//f_no的第i位是指:字符串s[i:]中,s[i]和s[i+1]不连在一起的解码方式
vector<int> f_lian(s.size(),0),f_no(s.size(),0);
//初始化f_no的最后一位
if(s.back()=='0')
f_no.back()=0;
else
f_no.back()=1;
for(int i=s.size()-2;i>=0;--i)
{
if(s[i]=='0')
{
if(s[i+1]=='0')
return 0;
f_lian[i]=0;
f_no[i]=0;
}
else if(s[i]>='3')
{
if(s[i+1]=='0')
return false;
f_no[i]=f_lian[i+1]+f_no[i+1];
f_lian[i]=0;
}
else if(s[i]=='1')
{
if(i==s.size()-2)
{
f_lian[i]=1;
f_no[i]=s[i+1]=='0'?0:1;
}
else if(s[i+1]=='0')
{
f_no[i]=0;
f_lian[i]=f_lian[i+2]+f_no[i+2];
}
else
{
f_no[i]=f_lian[i+1]+f_no[i+1];
f_lian[i]=f_lian[i+2]+f_no[i+2];
}
}
else// s[i]=='2'
{
if(i==s.size()-2)
{
f_no[i]=s[i+1]=='0'?0:1;
f_lian[i]=s[i+1]>='0'&&s[i+1]<='6'?1:0;
}
else if(!(s[i+1]>='1'&&s[i+1]<='6'))
{
f_lian[i]=s[i+1]=='0'?f_lian[i+2]+f_no[i+2]:0;
f_no[i]=f_lian[i+1]+f_no[i+1];
}
else if(s[i+2]!='0')
{
f_no[i]=f_lian[i+1]+f_no[i+1];
f_lian[i]=f_lian[i+2]+f_no[i+2];
}
else
{
f_lian[i]=0;
f_no[i]=f_lian[i+1]+f_no[i+1];
}
}
}
return f_lian[0]+f_no[0];
}
};
方法二:
类似斐波那契数列的求解方法:设f[i]代表s[0:i]所组成的字符串的解码数量,则f[i]=f[i-1],或f[i]=f[i-1]+f[i-2](当s[i-1]和s[i]组成11至19,或21至26时)。不要忘了判断不能解码的情况(即s[i]==‘0’,且s[i-1]不是'1'或'2'). 时间复杂度O(n),空间复杂度O(1)。
class Solution {
public:
int numDecodings(string s) {
if(s.empty() || s[0]=='0')
return 0;
if(s.size()==1)
return 1;
if(s[1]=='0' && s[0]!='1' && s[0]!='2')
return 0;
int n1=1,n2=lian(s[0],s[1])?2:1;
for(int i=2;i<s.size();++i)
{
if(s[i]=='0')
{
if(s[i-1]!='1' && s[i-1]!='2')
return 0;
int sum=n1;
n1=n2;
n2=sum;
}
else
{
int sum=n2;
if(lian(s[i-1],s[i]))
sum+=n1;
n1=n2;
n2=sum;
}
}
return n2;
}
bool lian(char a,char b)
{
if(a=='1' && b!='0')
return true;
if(a=='2' && b>='1' && b<='6')
return true;
return false;
}
};