class Solution {
public:
int solve(string nums) {
if (nums.empty() || nums[0] == '0') return 0;
int n = nums.length();
vector<int> dp(n + 1, 0);
dp[0] = 1; // 空字符串有一种解码方式
dp[1] = 1; // 第一个字符不是0,有一种解码方式
for (int i = 2; i <= n; i++) {
// 检查当前单个数字
int oneDigit = nums[i - 1] - '0';
int twoDigits = stoi(nums.substr(i - 2, 2));
// 如果当前数字不是0,可以单独解码
if (oneDigit != 0) {
dp[i] += dp[i - 1];
}
// 如果两个数字在10-26之间,可以组合解码
if (twoDigits >= 10 && twoDigits <= 26) {
dp[i] += dp[i - 2];
}
}
return dp[n];
}
};
我的想法是如果前一位与当前位i能够用单独和组合编码,dp[i]=2*dp[i-1],如果只能使用其中一种方式解码,那么dp[i] = dp[i-1],这是错误的
1. 状态转移错误
你的方法假设当前状态只依赖于前一个状态(dp[i-1]),但实际上:
单独编码:依赖前一个状态 dp[i-1]
组合编码:依赖前两个状态 dp[i-2]
这两种情况是互斥且独立的,应该分别计算并累加,而不是简单的乘以2。
2. 数学上的错误
假设在位置i有两种解码方式:
方式A:单独解码当前字符,有 dp[i-1] 种方式
方式B:组合解码最后两个字符,有 dp[i-2] 种方式
总的方式数应该是 dp[i] = dp[i-1] + dp[i-2],而不是 dp[i] = 2 × dp[i-1]。