• [LeetCode#91]Decode Ways


    Problem:

    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.

    Analysis:

    Note the transitional function!!!
    At first glance, it could be solved through recursive call. But we only care about the total count!!! Why we must follow that routinue.
    The difference here are only: count the present digit as a character, or count two digits as a character. For all chacter, we should ask us the same question. since there are only two possible situations, why not we use dynamic programming for it.
    The range of two digits in this problem is '00' - '99', we could intepret those two digits separately or together. 
    Suppose res[i] represents the sequences count from 0 to i.
    1.'00'
    res[i] = 0, since '00' is invalid and '0' is invalid.
    
    2. '01' - '09'
    res[i] = res[i-1], must be sperated.
    
    3. '10', '20'
    res[i] = res[i-2], the new added character must be combined with '1' or '2'
    
    4. '11-19', '21 - 26'
    res[i] = res[i-2] + res[i-1]
    
    5. '27-99' not include *0
    res[i] = res[i-1]
    
    ----------------------------------------------------
    1.'00'
    res[i] = 0, since '00' is invalid and '0' is invalid.
    ----------------------------------------------------
    6. *0 (exclude '10', '20')
    res[i] = 0
    
    Do you think the above analysis is too ugly and complex?
    When a '0' appears, we need to tackle so many different cases. The related program must be very ugly too!
    
    Can we find a way to avoid the complex checking?
    Yes!!!!
    Why not do the dynamic prgramming from right to left?
    
    '0*' must be invalid for both cases, we can directly ignore it.
    '01'. '0'is invalid, and '01' is also invalid. 
    for (int i = len-1; i >= 0; i--) {
        if (s.charAt(i) != '0') {
            ...
    }
    
    If s.charAt(i) is not equal to '0', 
    1. it must could be separately intepreted '1' .. '9' are valid.
    2. it might be valid for inteprrting together. '11' _ '26' are valid. (note: no '0' start)
    if (s.charAt(i) != '0') {
        dp[i] = dp[i+1];
        if (i < len-1 && Integer.parseInt(s.substring(i, i+2)) <= 26)
            dp[i] += dp[i+2];
    }
    
    How easy of this solution, right?
    Skills:
    How initiate the value for first intepreted character or 'two character'.
    Can you use 
    int[] dp = new int[len];
    dp[0] = 1
    Absolutely no!!!, what if the last character is '0'. like '20'
    And it would break the elegant code structure. 
    
    How about use a extra element?
    int[] dp = new int[len+1];
    dp[len] = 1;
    
    1. last character
    if the last element is '0'. 
    dp[len-1] still equal to 0
    if the last element is not '0'.
    dp[i] = dp[i+1];
    
    2. last two character
    if the second to last element is '0'
    dp[len-1] still equal to 0
    if the second to last element is not '0' and in the valid range '11 - 26'
    dp[i] += dp[i+2] (1);
    
    
    What a great skill!!!
    How to give the initial value for two case through a additional element, while keep the elegant code structure at the same time.

    Solution:

    public 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[len] = 1;
            for (int i = len-1; i >= 0; i--) {
                if (s.charAt(i) != '0') {
                    dp[i] = dp[i+1];
                    if (i < len-1 && Integer.parseInt(s.substring(i, i+2)) <= 26)
                        dp[i] += dp[i+2];
                }
            }
            return dp[0];
        }
    }
  • 相关阅读:
    【CF580D】Kefa and Dishes
    【poj3311】Hie with the Pie
    校外实习-7.7
    校外实习-7.6
    校外实习-7.5
    校外实习-7.4
    作业九-课程总结(补充)
    作业九-课程总结
    作业四——结对编程四则运算
    作业三
  • 原文地址:https://www.cnblogs.com/airwindow/p/4762412.html
Copyright © 2020-2023  润新知