原题链接在这里:https://leetcode.com/problems/decode-ways/
题目:
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<dp.length; i++){ 11 if(isValid(s.substring(i-1, i))){ 12 dp[i] += dp[i-1]; 13 } 14 if(isValid(s.substring(i-2, i))){ 15 dp[i] += dp[i-2]; 16 } 17 } 18 return dp[dp.length - 1]; 19 } 20 21 private boolean isValid(String s){ 22 if(s.charAt(0) == '0'){ 23 return false; 24 } 25 return Integer.valueOf(s) >= 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 }