LeetCode第91题(解码方法)

原题如下:

一条包含字母 A-Z 的消息通过以下方式进行了编码:

‘A’ -> 1
‘B’ -> 2

‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例 1:

输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)。
示例 2:

输入: “226”
输出: 3
解释: 它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6) 。

这题 你需要注意以下几点:
1).s的首部不能是0!!
2).中间部分可以是0但是 它的前面那个数字必须是1 或者2(以上两点需要在开始计算前 先遍历一遍)
3).计算过程中如果遇到0怎么办???(我们需要把这个0与他前面那个数字x(如果步骤1和步骤2做过了 只可能是1或者2)绑定在一起 )
4).绑定的那个 x不能再与(x之前那个数字组合在一起 假设前面那个数字存在的话) ps:::比如 1220 (“20”是要在一起的 同时22虽然我们可以解码出来一个字符 但是 20已经被绑住一起了!!!)
5).对于 一个串 s 他的解码个数是不是直接由 (前面s.size()-1 个推倒出来 的 比如s=123 假设我已经知道 “23”的解码个数为k 能否直接推倒 出 “123”的个数)????? ps::我们知道 这些数字只要组合起来<=26 是可以看成一个数的 所以 从后往前遍历到“1”的时候 其实 由两部分组成
第一 把“1”单独看 s 就是“23”的解码个数
第二把“12”单独看 s就是“3”的解码个数(注意 如果 s=1203 这个时候 只有第一种情况 你是不能把 12 合在一起看的 2必须要和0绑定在一起 也就是 4)中我们提到的情况)
于是 s(n)就等于以上两种情况的个数和(以此类推)

代码如下(其实只需要两个变量就行了,为了操作方便我直接开了一个数组(注意数组的size 要比s.size()大1) 此外我是从后往前遍历的 反过来 也是一样的道理):

	int numDecodings(string s) {
		for (int i = 0; i <= s.size() - 1; i++){
			if (s[i] == '0'){
				if (i == 0) return 0;
				else  {
					if (s[i - 1] == '1' || s[i - 1] == '2')continue;
					else return 0;
				}
			}
		}
		vector<int> total(s.size()+1);
		for (int i = 0; i <= total.size() - 1; i++)total[i] = 0;
		total[total.size() - 1] = 1;
		for (int end = s.size() - 1;end >= 0; end--){
			if (end == s.size() - 1) total[end] = 1;
			else{
				if (s[end] == '0'){
					total[end] = total[end + 1];
				}
				else{
					if (s[end + 1] == '0') total[end] = total[end + 1];
					else {//都不是0
						if (end + 2 <= s.size() - 1){
							if (s[end + 2] == '0') { total[end] = total[end + 1]; continue; }
						}
						string tmp = s.substr(end , 2);
						int t = atoi(tmp.c_str());
						if (t <= 26)  total[end] = total[end + 2] + total[end + 1]; 
						else total[end] = total[end + 1];
					}
				}
			}
		}
		return total[0];
	}

猜你喜欢

转载自blog.csdn.net/qq_42203013/article/details/82793392