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.
分析:
方法一:
看完题目之后首先想到了用递归的方法来解决这个问题,但是对于比较长的字符串出现了TLE(超时),下面是用递归实现的代码,这种方法的思想很简单,但是很耗时。
1 void getnum(string s, int &num) 2 { 3 if(s.size()==0 || s.size()==1) 4 { 5 if(s.size()==1 && s[0]==‘0‘) 6 return; 7 num++; 8 return; 9 } 10 11 int a,b; 12 istringstream in1(s.substr(0,1)); 13 istringstream in2(s.substr(0,2)); 14 15 in1>>a; 16 in2>>b; 17 18 if(a>=1 && a<=9) 19 getnum(s.substr(1), num); 20 21 if(b>=10 && b<=26) 22 getnum(s.substr(2), num); 23 } 24 25 class Solution { 26 public: 27 int numDecodings(string s) { 28 int num=0; 29 getnum(s, num); 30 return num; 31 } 32 };
方法二:
用动态规划的思想来分析题目,假设f(n)表示由给定输入的前n个字符构成的字符串所对应的解码方式个数,用a表示第n个字符所代表的数字,b表示由第n-1个字符和第n个字符所构成的二位数字,
如果a>=1 && a<=9,那么第n个字符可以单独解码,如果b>=10 && b<=26,那么第n-1个字符和第n个字符可以组合解码,以下简称a可以解码,b可以解码。考虑四种情况:
(1)a和b都可以解码,不难得出,此时,f(n)=f(n-1)+f(n-2);
(2)如果a可以解码,b不可以解码时,f(n)=f(n-1);
(3)如果a不可以解码,b可以解码时,f(n)=f(n-2);
(4)a和b都不能解码时,f(n)=0。
这种方法的运行速度很快,运行255个测试例子,耗时72ms,而用方法一耗时好几分钟。
1 class Solution { 2 public: 3 int numDecodings(string s) { 4 if(s.size()==0) 5 return 0; 6 7 int num1=1, num2=0; 8 int a,b; 9 istringstream in1(s.substr(0,1)); 10 in1>>a; 11 if(a>=1 && a<=9) 12 num2++; 13 if(s.size()==1) 14 return num2; 15 16 for(unsigned i=2; i<=s.size(); i++) 17 { 18 istringstream in1(s.substr(i-1,1)); 19 istringstream in2(s.substr(i-2,2)); 20 in1>>a; 21 in2>>b; 22 int temp = num1; 23 num1 = num2; 24 num2 = 0; 25 if(a>=1 && a<=9) 26 num2 += num1; 27 28 if(b>=10 && b<=26) 29 num2 += temp; 30 } 31 return num2; 32 } 33 };
[LeetCode OJ] Decode Ways