leetcode:91. 解码方法
·
题目来源
题目描述


class Solution {
public:
int numDecodings(string s) {
}
};
题目分析
题意分析
我们先来理解一下题目的解码规则

如例子s = “226”,可以分为两种情况:
- 将每一个数字单独编码,因此可以解码成
"BBF"(2 2 6) - 将相邻两位数字组合起来解码(组合的数字范围在
10 ~ 26之间),因此可以解码成"BZ"(2 26),"VF"(22 6)。
两种情况是或的关系,互不影响,将其相加,那么226共有3种不同的解码方式
不难发现,对于字符串s的某个位置而言,我们只关心[位置i自己能否形成独立的item和[位置i能够与上一位置(i - 1)能否形成item]
典型的划分型动态规划
这道题要求解码方法,除去一些限制条件(比如说一位数时不能为0,两位数不能大于 26,其十位上的数也不能为0),跟爬梯子基本没啥区别,也勉强算特殊的斐波那契数列
- 定义dp:dp[i] 表示s中前i个字符组成的子串的解码方法的个数,长度比输入数组长多多1,并将 dp[0] 初始化为1。
实现:
class Solution {
public:
int numDecodings(string s) {
if (s.empty() || s[0] == '0') return 0;
vector<int> dp(s.size() + 1, 0);
dp[0] = 1;
for (int i = 1; i < dp.size(); ++i) {
if (s[i - 1] != '0') dp[i] += dp[i - 1];
if (i >= 2 && s.substr(i - 2, 2) <= "26" && s.substr(i - 2, 2) >= "10") {
dp[i] += dp[i - 2];
}
}
return dp.back();
}
};
实现:
class Solution {
public:
int numDecodings(string s) {
if (s.empty() || s[0] == '0') return 0;
vector<int> dp(s.size() + 1, 0);
dp[0] = 1;
for (int i = 1; i < dp.size(); ++i) {
dp[i] = (s[i - 1] == '0') ? 0 : dp[i - 1];
if (i > 1 && (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6'))) {
dp[i] += dp[i - 2];
}
}
return dp.back();
}
};
类似题目
| 题目 | |
|---|---|
| leetcode:91. 解码方法Decode Ways | |
leetcode:639. *可以匹配多个字符时,有多少解码方法 II Decode Ways II | |
| leetcode:70. 爬楼梯 Climbing Stairs | 动态规划 |
更多推荐
所有评论(0)