一、题意
一条包含字母 A-Z 的消息通过以下映射进行了编码:
A->1
B->2
…
Z->26
给出一串数字的字符串,对其进行解码,求有几种结果。
如 “11106”
可以解码成 A A J F(‘1’,‘1’,‘10’,‘6’)或者KJF(‘11’,‘10’,‘6’),但是不能分解成(‘11’,‘1’,‘06’),因为’06’不等于’6’
二、解法
解法:
动态规划
设f[i]代表s前i个字符的解码方案数:
当取一个字符到i时,判断s[i]是否等于’0’,不是则加上f[i-1]
当取两个字符到i时,判断s[i-1]是否等于’0’以及s[i-1]和s[i]是否能组成’1’到’26’之间的数,能则加上f[i-2]
f[i]由f[i-1]上一次的状态和f[i-2]上上次的状态组成,可以由两个变量,表示f[1],代表当前结果(i++后这就相当于f[i-1]),f[0]代表f[i-2]。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
三、代码
解法:
int numDecodings(string s) {
int f[2]={0};
f[0]=1;
f[1]=s[0]!='0'?1:0;
for(int i=1;i<s.size();i++){
int v=0;
if(s[i]!='0'){
v += f[1];
}
if(s[i-1]!='0'&&(s[i-1]-'0')*10+s[i]-'0'<=26){
v+= f[0];
}
f[0] =f[1];
f[1]= v;
}
return f[1];
}
四、总结
只是一道斐波那契数列的变形题,类似青蛙跳台阶。可惜没有看出来,一开始想着求出每个字符是否符合条件的结果,再求每两个=个字符是否符合条件的结果,然后再串起来求结果,发现使用1或2个字符的时候情况挺复杂。
五、引用
[1] leetcode:91. Decode Ways
[2] leetcode:91. Decode Ways官方解法