Sunday, June 1, 2014

Decode Ways

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