Please check comments below for understanding the code. Any questions? Please let me know.
public class Solution {
public int numDecodings(String s) {// if step is 1, only 1 or 0 way to decode, depending on whether the char is '0', if step is 2
if (s == null) return 0;
if (s.equals("") || s.equals("0")) return 0;
if (s.length() < 2) return 1;
HashMap<Integer,Integer> record = new HashMap<Integer,Integer>();
// record is used to store num of decodings corresponding to the index, so DP is applied
int result = numDecode(s,0,record);
return result;
}
// numDecode is used to compute the number of decoding ways from startIdx of String s.
// for this question, since at most we get '26' for each letter, we only need to care about current and next // char, i.e. 2 digits. One thing we should know is that when we take one way(a few steps) from startIdx,
// then go through all chars in s, then this way can be considered as successful, or valid. If startIdx finally // gets larger than or equal to s.length() - 1, we should return 1, except that the last digit or char of s is 0, in // which case 0 is returned, since only '10' or '20' is valid case
public int numDecode(String s, int startIdx, HashMap<Integer,Integer> record){
if(record.containsKey(startIdx)) return record.get(startIdx);
if(startIdx > s.length() - 1){
record.put(startIdx,1);
return 1;
}
if(startIdx <= s.length() - 1 && s.charAt(startIdx) == '0') {// case s.charAt(startIdx) == '0' return 0
record.put(startIdx,0);
return 0;
}else{
if(startIdx == s.length() - 1){
record.put(startIdx,1);
return 1;
}
}
int count;
if((s.charAt(startIdx)-'2' )>0) {// if it is '3' or larger, only take step as 1 to decode it, go to next index
count = numDecode(s,startIdx+1,record);
record.put(startIdx,count);
return count;
}
else{
if((s.charAt(startIdx)-'1' ) == 0) {// if is '1', both step 1 or 2 is okay, for '10' //numDecode(s,startIdx+2,record) return 1,
//numDecode(s,startIdx+1,record) return 0, sum is 1, correct
count = numDecode(s,startIdx+1,record) + numDecode(s,startIdx+2,record);
record.put(startIdx,count);
return count;
}
else {// in this case s.charAt(startIdx) == 2
if((s.charAt(startIdx + 1) - '6') <= 0){//smaller than or equal to '26', both step 1 or 2 okay, for '20' //numDecode(s,startIdx+2,record) return 1,
//numDecode(s,startIdx+1,record) return 0, sum is 1, correct
count = numDecode(s,startIdx+1,record) + numDecode(s,startIdx+2,record);
record.put(startIdx,count);
return count;
}
else {// larger than '26', only step 1 method can be used
count = numDecode(s,startIdx+1,record);
record.put(startIdx,count);
return count;
}
}
}
}
}
No comments:
Post a Comment