标签:
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.
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] = dp[1] = 1; for (int i = 1; i < s.length(); i++) { char pre = s.charAt(i-1); char c = s.charAt(i); if (c == '0') { if (pre > '2' || pre == '0') return 0; else dp[i+1] = dp[i-1]; } else { dp[i+1] = dp[i]; if (pre != '0' && (pre-'0')*10 + (c-'0') <= 26) dp[i+1] += dp[i-1]; } } return dp[dp.length-1]; }
此方法是从前往后递推,dp[i+1]是指以s.substring(0,i+1)字串的解,但是此代码比较繁杂,因为就是0这个坑。
看下面的代码:
public int numDecodings(String s) { int n = s.length(); if (n == 0) { return 0; } int[] table = new int[n+1]; table[n] = 1; table[n-1] = s.charAt(n-1) != '0' ? 1 : 0; for (int i = n-2; i >= 0; i--) { if (s.charAt(i) == '0') { table[i] = 0; } else { int num = Integer.parseInt(s.substring(i, i+2)); if (num <= 26) { table[i] = table[i+1]+table[i+2]; } else { table[i] = table[i+1]; } } } return table[0]; }其实状态转移方程是基本一样的,差别就是一个从开始扫描,一个从数组尾部扫。从尾部扫描的一个好处是当s[i] = 0的时候,此时dp[i] = 0,因为以0开头的字符串都是不合法的,都是0。而以0结尾的字符串你不能直接按0,所以有很复杂的条件语句。这一点就决定了从尾部扫描要比从头扫描要简单。
另外一种思考问题的方法,从头到尾,还是从尾到头。一些问题逆向比较简单。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/my_jobs/article/details/47981897