• 91. Decode Ways


    题目:

    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.

    链接: http://leetcode.com/problems/decode-ways/

    题解:

    一看到这题就想到了爬楼梯climb stairs,典型的一维DP。下面就用一维DP来做。先建立数组dp = new int[s.length() + 1], 初始化一个数字的情况dp[0] = 1, 两个数字组成一个两位数字的情况dp[1] = 1。接下来写出循环体,先算一个数字的情况,当s.charAt(i - 1)不为0的时候,dp[i] = dp[i - 1], 否则dp[i] = 0。 接下来考虑两位数字,当由i-2和i-1这两位组成的数字大于等于10,小于等于26时,dp[i] += dp[i - 2], 否则忽略此种情况。

    Time Complexity - O(n), Space Complexity - O(n)。

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

    可以继续优化Space Complexity至O(1).

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

    题外话: 使用DP思想的一些题目 - decode ways, climb stairs, find LCS(longest common subsequence), find longest ascending subsequence, fine longest descending subsequens, 背包问题,poj滑雪,等等。DP这种重要的编程思想要好好学习领会。

    二刷:

    还是使用dp,新建一个dp数组比较好理解,但空间的优化却不是很熟练。对于dp,还是需要加强狠练。如何才能写出优雅而且精炼的代码是个问题。 Elegant and concise

    Java:

    Time Complexity - O(n), Space Complexity - O(n)。

    public class Solution {
        public int numDecodings(String s) {
            if (s == null || s.length() == 0 || s.charAt(0) == '0') {
                return 0;
            }
            int len = s.length();
            int[] numWays = new int[len + 1];
            numWays[0] = 1;      // empty string
            numWays[1] = 1;      // one char
            for (int i = 2; i <= len; i++) {
                int num = Integer.parseInt(s.substring(i - 2, i));
                numWays[i] = (num <= 26 && num >= 10) ? numWays[i - 2] : 0;
                numWays[i] += (s.charAt(i - 1) != '0') ? numWays[i - 1] : 0;
            }
            return numWays[len];
        }
    }

    因为do[i] 只和dp[i - 1]以及dp[i - 2]有关,我们可以优化空间到O(1)。就是使用两个变量来代表numWays[i - 1]和numWays[i - 2], 以及一个变量res来代表它们的和,接下来三个一起倒腾倒腾就好了

    Time Complexity - O(n), Space Complexity - O(1)。

    public class Solution {
        public int numDecodings(String s) {
            if (s == null || s.length() == 0 || s.charAt(0) == '0') {
                return 0;
            }
            int len = s.length();
            int lastTwoSteps = 1; // empty string
            int lastOneStep = 1;   // one char     
            int res = 0;
            for (int i = 2; i <= len; i++) {
                int num = Integer.parseInt(s.substring(i - 2, i));
                res += (num <= 26 && num >= 10) ? lastTwoSteps : 0;
                res += (s.charAt(i - 1) != '0') ? lastOneStep : 0;
                lastTwoSteps = lastOneStep;
                lastOneStep = res;
                res = 0;
            }
            return lastOneStep;
        }
    }

    题外话:

    2/11/2016:

    时间相当紧张,要复习LC,刷面经,多线程,设计模式,系统设计。自己提速却不是很成功,转进努力吧。要深入思考。

    自己与去年9月开始刷题以来,有什么改变和进步呢??? 好像并没有实质性的突破....要说进步的地方,可能就是养成了学习的习惯吧

    Reference:

    https://leetcode.com/discuss/49719/dp-with-easy-understand-java-solution

    https://leetcode.com/discuss/8527/dp-solution-java-for-reference

  • 相关阅读:
    Highcharts之饼图
    设计模式学习之原型模式
    jQuery学习之结构解析
    JS学习之闭包的理解
    JS学习之prototype属性
    JS学习之事件冒泡
    Mybatis学习之JDBC缺陷
    Spring学习之Aop的基本概念
    Struts学习之值栈的理解
    Struts学习之自定义结果集
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4437154.html
Copyright © 2020-2023  润新知