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.
[解题思路]
本题一开始没有思路,上网搜索后发现与上楼梯那题类似
使用动态规划来解决问题,使用动态规划的目的是降低问题维度,通过解决子问题来来求解原问题
在求解子问题的过程中通过memoization来避免计算重复子问题,不过由于需要存储子问题的解,因而会有额外的空间消耗
令f(n)表示长度为n的输入解码方法,则有如下状态迁移方程:
f(n) = f(n-1) + f(n-2); //s[n] is valid encoding char && s[n-1][n] is valid encoding char
f(n) = f(n-1); //s[n] is valid encoding char while s[n-1][n] is not valid encoding char
f(n) = f(n-2); //s[n] is not valid encoding char && s[n-1][n] is valid encoding char
f(n) = 0; //s[n] is not valid encoding char && s[n-1][n] is not valid encoding char
1 private static int generate(String s) { 2 int len = s.length(); 3 if (0 == len || s.charAt(0) == '0') { 4 return 0; 5 } 6 int[] dp = new int[len + 1]; 7 dp[0] = 1; 8 dp[1] = 1; 9 for (int i = 2; i < len + 1; i++) {10 char curChar = s.charAt(i - 1);11 int curNum = curChar - '0';12 // s[i] is not valid13 if (curNum == 0) {14 String twoNum = s.substring(i - 2, i);15 // s[i-1][i] is valid16 if (Integer.parseInt(twoNum) <= 2617 && Integer.parseInt(twoNum) >= 10) {18 dp[i] = dp[i - 2];19 } else {20 dp[i] = 0;21 }22 }23 // s[i] is valid24 else {25 String twoNum = s.substring(i - 2, i);26 // s[i-1][i] is valid27 if (Integer.parseInt(twoNum) <= 2628 && Integer.parseInt(twoNum) >= 10) {29 dp[i] = dp[i - 1] + dp[i - 2];30 } else {31 dp[i] = dp[i - 1];32 }33 }34 }35 36 return dp[len];37 }