题目
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given a non-empty string containing only digits, determine the total number of ways to decode it.
思路
- 思考:当输入一个字符串数字S0...Sn的时候,他的结果能通过S0...Sn-1推导得到吗?
- 当Sn为'0'的时候,因为0不能单独解码,所以必须依赖Sn-1,所以此时Sn-1Sn可以看成一个整体,那么此时S0...Sn的情况总数跟S0...Sn-2是一样的
- 当Sn-1Sn的数字不在10-26之间,那么S0...Sn相较于S0...Sn-1多了一位数字,且该数字必须单独存在,那么S0...Sn的情况总数跟S0...Sn-1是一样的
- 当Sn-1Sn的数字在10-26之间,那么根据上述两种情况的描述,都可以满足,所以此时S0...Sn的情况总数等于S0...Sn-2加上S0...Sn-1的和。
- 有了转移方程表达式后,来看看基础的解。当s的长度为1且不为'0'的时候,解为1,由于转移方程依赖n-2,所以这里定义当s是空字符串的时候,解为1。
var numDecodings = function(s) {
if (s[0] === '0' || s.indexOf('00') >= 0) return 0;
if (s.length < 2) return 1;
var lastLast = 1;
var last = 1;
var nowRes = 0;
for (var i = 1; i < s.length; i++) {
const lastTwoNumber = Number(`${s[i - 1]}${s[i]}`);
if (s[i] === '0') {
if (s[i - 1] > 2) {
return 0;
}
nowRes = lastLast;
} else if (lastTwoNumber > 26 || lastTwoNumber < 10) {
nowRes = last;
} else {
nowRes = lastLast + last;
}
lastLast = last;
last = nowRes;
}
return nowRes;
};
思路跟爬楼梯问题有点像,但是比较难,边界问题比较多,比如当前的字符是'0'时,如果前一位的字符大于2,那么根据题意是不存在30+的解码的,所以此时可以短路直接返回结果0。