LeetCode91——解码方法
题目描述
一条包含字母 A-Z 的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
题目数据保证答案肯定是一个 32 位的整数。
示例
输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。
题目分析
唉,其实就是一个上楼梯的有限制版,处理好边界,简单动归就完事了,好菜啊
对于字符串 \(s\) 来说,设 \(dp[i]\) 表示前 \(i\) 个字符种有 \(dp[i]\) 种组合方式可以用来解码。
对于 \(s[i]\) 来说:
- 若
s[i] = '0',则此时,只有当s[i-1]='1'或s[i-1]='2',才能保证可以正确解码,因为 0 不能被单独解码,此时dp[i] = dp[i-2](因为 0 和前一位组合,所以方案数不发生变化);否则直接return 0,因为0不能被单独用来解码。 - 若
s[i] != '0':- 若
s[i-1] = '1',则此时,\(s[i]\) 既可以自行单独用来解码,此时方案数为 \(dp[i-1]\) ;也可以与 \(s[i-1]\) 组合进行解码,此时方案数为 \(dp[i-2]\)。两种选择的方案数相加即为此种情况的总方案数,即dp[i] = dp[i-1] + dp[i-2]。 - 若
s[i-1] = '2',则此时,只有当s[i] >= 1 && s[i] <= 6时,\(s[i]\) 才既可以自行单独进行解码,也可以与 \(s[i-1]\) 组合进行解码,解释同上,此时,dp[i] = dp[i-1] + dp[i-2]。
- 若
- 若不符合以上所述情况,此时 \(s[i]\) 只能自行单独解码,此时
dp[i] = dp[i-1]
代码
接下来上代码,由于 \(s[0]\) 表示第一个字符,故转移方程需要稍作调整。
同时,我们让dp[0] = 1,没什么实际意义,但是为了理解方便,可以类比上楼梯,理解为前0个字母的解码方式一共有一种方案(好像不是那么恰当哈,不过差不多那个意思)
class Solution {
public int numDecodings(String s) {
if(s.length() == 0 || s.charAt(0) == '0'){
return 0;
}
int n = s.length();
char[] arr = s.toCharArray();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 1; i < n;i ++){
//转移方程调整解释:i=1时,表示第2个字符,所以我们把dp[i] 改成dp[i+1],以此类推对转移方程进行微调
if(arr[i] == '0'){
if(arr[i - 1] == '1' || arr[i - 1] == '2'){
dp[i + 1] = dp[i - 1];
}else{
return 0;
}
}else if(arr[i - 1] == '1' || (arr[i - 1] == '2' && arr[i] <= '6')){
dp[i + 1] = dp[i] + dp[i - 1];
}else{
dp[i + 1] = dp[i];
}
}
return dp[n];
}
}

浙公网安备 33010602011771号