原题目
一条包含字母 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
题目分析
方法一:记忆化搜索
方法二:一维动态规划
方法三:常数级动态规划
方法四:改进方法三
完整代码
方法一:
int *dp;
int dfs(char *s,int start)
{
if(s[start]=='\0')
return 1;
if(dp[start]!=-1)return dp[start];
int a=0,b;
if(s[start]!='0')
a+=dfs(s,start+1);
if(s[start+1]!='\0')
{
b=(s[start]-'0')*10+s[start+1]-'0';
if(b>=10&&b<=26)
a+=dfs(s,start+2);
}
dp[start]=a;
return a;
}
int numDecodings(char * s){
dp=(int *)malloc(sizeof(int)*(strlen(s)+1));
memset(dp,-1,sizeof(int)*(strlen(s)+1));
return dfs(s,0);
}
方法二:
int numDecodings(char * s){
int *dp=(int *)malloc(sizeof(int)*(strlen(s)+1));
memset(dp,0,sizeof(int)*(strlen(s)+1));
dp[0]=1;
for(int i=1;i<=strlen(s);i++)
{
if(s[i-1]=='0')
{
dp[i]=0;
}
else
dp[i]+=dp[i-1];
if(i-2>=0)
{
int b=(s[i-2]-'0')*10+s[i-1]-'0';
if(b>=10&&b<=26)
dp[i]+=dp[i-2];
}
}
return dp[strlen(s)];
}
方法三:
int numDecodings(char * s){
int pre=0,cur=1;
for(int i=0;i<strlen(s);i++)
{
int temp;
if(s[i]=='0')
temp=0;
else
{
temp=cur;
}
if(i-1>=0)
{
int b=(s[i-1]-'0')*10+s[i]-'0';
if(b>=10&&b<=26)
temp+=pre;
}
pre=cur;
cur=temp;
}
return cur;
}
方法四:
int numDecodings(char * s){
int k=1;
int sum=(s[0]!='0');
for(int i=1;i<strlen(s);i++)
{
int temp=k;
k=sum;
int num=10*(s[i-1]-'0')+s[i]-'0';
sum=temp*(9<num&&num<=26)+sum*(s[i]>'0');
}
return sum;
}