[leetcode]91. Decode Ways解码方法

时间:2023-12-28 11:32:32

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

思路:

解法一:recursion, 找到全部可能的解密方法(会TLE)

time :  O(2 ^ n) 因为是一个二叉树, 其高度最高为n,  所以时间复杂度是O(2 ^ n)

space: O(n)   跟数的高度有关,就是n层

 public int numDecodings(String s ){
if(s == null || s.length() == 0) retrun 0;
return numDecodings(s.toCharArray(), 0);
} private int numDecodings(char[] array, int level){
if(level == array.length){return 1;}
int ways = 0;
if(array[level] != ‘0’) {
ways += numDecodings(array, level + 1);
  }
  if(validEncoding(array, level)){
  ways += numDecodings(array, level + 2);
  }
return ways;
} private boolean validEncoding(char[]array, int start){
if(start + 1 >= array.length) return false;
if(array[start] = ‘1’) return true;
if(array[start] == ‘2’ && array[start + 1] –‘6’ <=0) return true;
return false;
}

解法二:自顶向下记忆化搜索(recursion + memorization)

time :  O(1) * (n + 1 )  = O(n)

space: O(n)

 class Solution {
public int numDecodings(String s ){
if(s == null || s.length() == 0) return 0;
int[] m = new int[s.length() + 1];
Arrays.fill(m, -1);
return numDecodings(s.toCharArray(), 0, m);
} private int numDecodings(char[] array, int level, int[] m){
if(m[level] != -1){
return m[level];
}
if(level == array.length){
m[level] = 1;
return 1;
}
int ways = 0;
if(array[level] != '0') {
ways += numDecodings(array, level + 1, m);
}
if(validEncoding(array, level)){
ways += numDecodings(array, level + 2, m);
}
return ways;
} private boolean validEncoding(char[]array, int start){
if(start + 1 >= array.length) return false;
if(array[start] == '1') return true;
if( array[start] == '2' && array[start + 1] - '6' <= 0 ){
return true;
}
return false;
}
}

解法三: 自底向上的dp

 class Solution {
public int numDecodings(String s) {
if (s == null || s.length() == 0) return 0;
int len = s.length();
int[] dp = new int[len + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;
for (int i = 2; i <= len; i++) {
int first = Integer.parseInt(s.substring(i - 1, i));
int second = Integer.parseInt(s.substring(i - 2, i));
if (first >= 1 && first <= 9) {
dp[i] += dp[i - 1];
}
if (second >= 10 && second <= 26) {
dp[i] += dp[i - 2];
}
}
return dp[len];
}
}