Question
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.
本题难度Medium。
DP
【复杂度】
时间 O(N) 空间 O(N)
【思路】
这道题有点像[LeetCode]Climbing Stairs,但比它复杂点。我本来是用dfs来做的,简单直观但是超时。对于这种数组问题,剩下的可选方案也就是DP了。
假设数组元素dp[i]表示从头到字符串的第i位一共有多少种解码方法的话,那么如果字符串的第i位不为'0',就可以在第i-1位的基础上继续解码,dp[i]+=dp[i-1];;如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们可以在第i-2位的解码方法上继续解码,dp[i]+=dp[i-2];。这里要清楚不是0到26,对于类似于"02"这样的是被判定为不可解码的。
【附】
这里有个技巧:
dp[i]并不对应s的第i个字符,而是对应于s的第i-1个字符,有点像链表中的fake节点功能。令dp[0]=1;而dp[1]=s.charAt(0)=='0'?0:1;,这样就可以应对"20"这样的情况:
![这里写图片描述 (low pass)[LeetCode]Decode Ways_leetcode](https://file.cfanz.cn/uploads/png/2023/02/02/7/1XNL4584dA.png)
【注意】
如果字串的长度为0,要返回0。(代码5-6行)
【代码】
public class Solution {
public int numDecodings(String s) {
//require
int size=s.length();
if(size<1)
return 0;
int[] dp=new int[size+1];
dp[0]=1;
dp[1]=s.charAt(0)=='0'?0:1;
//invariant
for(int i=2;i<=size;i++){
dp[i]+=s.charAt(i-1)=='0'?0:dp[i-1];
int tmp=Integer.parseInt(s.substring(i-2,i));
dp[i]+=(10<=tmp&&tmp<=26)?dp[i-2]:0;
}
//ensure
return dp[size];
}
}参考
[Leetcode] Decode Ways 解码方式










