一条包含字母 A-Z 的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数
输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)
int length = s.length();
//第一个数0肯定就非法了
if (s.charAt(0) == '0') return 0;
//重要
//建立了有s.length() + 1个元素的数组,下标最长到s.length()
int[] dp = new int[s.length() + 1];
dp[0] = dp[1] = 1;
//状态转移矩阵的i这里跟string的定位的j不一致
//因为如果j=i=1,dp[i]=dp[i-1]+dp[i-2] i=1 i-2就越界
for (int i = 2; i <= s.length(); i++) {
//如果该位不为'0',说明该位单独成字母合法
if (s.charAt(i - 1) != '0') {
dp[i] += dp[i - 1];
}
//如果后两位能组成"1x"(x为任意数字)或者"2x"(x小于7),说明最后两位组成字母合法
if ((s.charAt(i - 2) == '1') || (s.charAt(i - 2) == '2' && s.charAt(i - 1) <= '6')) {
dp[i] += dp[i - 2];
}
}
return dp[s.length()];
}
动态规划
- dp[]是状态转移矩阵,dp[i]代表元素个数为i时所拥有的的状态总数
- 动态规划的意思就是说当前的状态 dp[i]跟之前时刻的状态有关(可能跟dp[i-1,dp[i-2]等等之前的时刻有关系)
- 要根据当前时刻的状态来采取不同时刻的状态转移方程(dp[i]=dp[i-1]还是dp[i-1]+dp[i-2],根据当前的状态决定的(判断时有可能跟前面的联合在一起一起判断),例如
(s.charAt(i - 2) == '1') || (s.charAt(i - 2) == '2' && s.charAt(i - 1) <= '6'))
如果当前元素i不会对状态数产生影响的话
dp[i]=dp[i-1];
- 状态转移矩阵中的dp[i]跟字符串中charAt(j) i和j不一定是相等的
- 这道题中如果相等dp[1]代表只有一个元素的时候,charAt(1)指向的是字符串中第二个元素了,自己写的少没注意,这里一定要注意