Link: https://oj.leetcode.com/problems/decode-ways/
My thought:
e.g. s = "123", s.length = 3. We can choose to split at position i after char i [0, n-1]. So there are 2^(n-1) .
But I still need to validate whether the splitted numbers are between [1, 26]
Approach I: DP from left to right
Time: O(n), Space: O(n)
Reference: http://moisellegyg.blogspot.com/2014/04/leetcode-decode-ways.html
- s has only one character. If the character is '0', then return 0. Otherwise, return 1.
- s has at least two characters. We maintain an array count[n+1] to record the number of ways to decode s. Let count[i] be the number of ways to decode s[0..i-1]. We initialize count[0] = 1 and count[1] = 1.
- If s[i-1]!='0', which means we can decode s[i-1] to some letter, then count[i] = count[i-1]
- If s[i-1,i] represents an integer in the range of [10,26], which means we can decode s[i-1,i] to some letter, then count[i] += count[i-2].
- s[n] is the number of ways to decode s.
public class Solution {
//DP: from left to right. <span style="font-family: Arial, Helvetica, sans-serif;">ways[i]表示s[0...i-1]的解码方法数目</span>
public int numDecodings(String s) {
if(s == null || s.length() == 0) return 0;
int[] ways = new int[s.length()+1];
ways[0] = 1;//why>
if(s.charAt(0) != '0'){
ways[1] = 1;
}
for(int i = 2; i <= s.length(); i++){
if(s.charAt(i-1) != '0'){
ways[i] = ways[i-1];
}
else{
ways[i] = 0;
}
if(s.charAt(i-2) == '1' || (s.charAt(i-2) == '2' && s.charAt(i-1) <= '6')) {
ways[i] += ways[i-2];
}
}
return ways[s.length()];
}
}
http://blog.csdn.net/linhuanmars/article/details/24570759
has an Space = O(1) solution
Approach II: DP from right to left
public class Solution {
//I don't understand what's the benefit of doing from right to left
public int numDecodings(String s) {
if(s == null || s.length() == 0) return 0;
int[] ways = new int[s.length()+2];
for(int i = 0; i < ways.length; i++){
ways[i] = 1;
}
for(int i = s.length()-1; i>=0; i--){
if(s.charAt(i) == '0'){
ways[i] = 0;
}
else{
ways[i] = ways[i+1];
}
if( i + 1 < s.length() && ((s.charAt(i) == '1' || (s.charAt(i) == '2' && s.charAt(i+1) <= '6')))) {
ways[i] += ways[i+2];
}
}
return ways[0];
}
}