题目:
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.
可采用动态规划的思想来解决,英文字母可映射到1到26个数字,令F(n)表示n个数字共有多少种解码方式,a[]为输入的一串数字,那么我们便可以的到如下的递推公式。
若a[n] != 0,且 (a[n-1]*10+a[n] >= 1 && a[n-1]*10+a[n] <= 26) F(n) = F(n-1)+F(n-2);
若a[n] != 0, 且 (a[n-1]*10+a[n] == 0 || a[n-1]*10+a[n] > 26) F(n) = F(n-1);
若a[n] == 0,且 (a[n-1]*10+a[n] >= 1 && a[n-1]*10+a[n] <= 26) F(n) = F(n-2);
若a[n] == 0, 且 (a[n-1]*10+a[n] == 0 || a[n-1]*10+a[n] > 26) F(n) =0;
由以上几个递推公式,便可得出正确的结果,最后输出F(n)即可。
一种c++的实现方式如下:
#include<iostream>
#include<string>
using namespace std;
class Solution {
public:
int numDecodings(string s) {
int num = s.length();
if(num == 0) return 0;
if(s[0] == '0') return 0;
int *res = new int[num+1];
res[0] = 1;
res[1] = 1;
for(int i = 1; i < num; i++) {
string temp;
temp = s.substr(i-1,2);
if(isvalid2(temp) && isvalid1(s[i])) {
res[i+1] = res[i]+res[i-1];
} else if(isvalid2(temp) && !isvalid1(s[i])) {
res[i+1] = res[i-1];
} else if(!isvalid2(temp) && isvalid1(s[i])) {
res[i+1] = res[i];
} else {
res[num] = 0;
break;
}
}
return res[num];
}
//判断一个数字是否合法
bool isvalid1(char s) {
if(s == '0') {
return false;
} else {
return true;
}
}
//判断两个数字是否合法
bool isvalid2(string s) {
if(s[0] == '0') {
return false;
}
int n;
n = (s[0]-'0')*10 + (s[1]-'0');
if(n > 26) return false;
return true;
}
};