原题链接在这里:
题目:
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.
题解:
DP题. 要求的是decode的方法. 需要保留的历史信息是到当前字符decode的方法. 用array保存.
递推和等台阶的题目很像. 以"321" 为例,到了第三位时, s.substring(i-1, i) = "1"是 valid的, s.substring(i-2, i) = "21" 也是valid的.
dp[i] = dp[i-1] + dp[i-2].
答案是dp[dp.length-1].
初始化用到前两个, 所以要有两个base case. dp[0] = 1. dp[1]看第一个字符是否是'0', 若不是, dp[0]=1.
Note: 0 非常烦人. 若是string 是"09","10", 对应的数字9, 10都在1到26之间,但“0”根本就不能decode, 所以任何包含 "0"的字符串都是非法的, return false.
Time Complexity: O(n). Space: O(n). n = s.length().
AC Java:
1 public class Solution { 2 public int numDecodings(String s) { 3 if(s == null || s.length() == 0){ 4 return 0; 5 } 6 int [] dp = new int[s.length()+1]; 7 dp[0] = 1; 8 dp[1] = isValid(s.substring(0,1)) ? 1 : 0; 9 10 for(int i = 2; i= 1 && Integer.valueOf(s) <= 26;26 }27 }
只用到前面两个历史值. 可以降维处理.
Time Complexity: O(s.length()). Space: O(1).
AC Java:
1 public class Solution { 2 public int numDecodings(String s) { 3 if(s == null || s.length() == 0){ 4 return 0; 5 } 6 7 int first = 1; 8 int second = isValid(s.substring(0,1)) ? 1 : 0; 9 10 for(int i = 2; i<=s.length(); i++){11 int third = 0;12 if(isValid(s.substring(i-1, i))){13 third += second;14 }15 if(isValid(s.substring(i-2, i))){16 third += first;17 }18 19 first = second;20 second = third;21 }22 return second;23 }24 25 private boolean isValid(String s){26 if(s.charAt(0) == '0'){27 return false;28 }29 return Integer.valueOf(s) >= 1 && Integer.valueOf(s) <= 26;30 }31 }
跟上.