算法课第10周第3题——91. Decode Ways
来源:互联网 发布:同在一起网络剧 编辑:程序博客网 时间:2024/05/16 18:36
题目描述:
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1'B' -> 2...'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
程序代码:
class Solution {public:int numDecodings(string s) {int n = s.size();vector<int> f(n + 1, 0);// 第一位为0则无法解码,输出为0if (s[0] == '0') {return 0;}// 其余情况f[1] = 1else {f[1] = 1;}// 前两位在11~19或21~26时,f[2]=2,即前两位可以为一个十位数或两个个位数;// 第一位为0,或第二位为0且前两位不为10或20时,无法解码,输出0;// 其余情况f[2] = 1, 即需要将前两位拆成两个个位数.if ((s[0] == '1' && s[1] != '0') || s[0] == '2' && s[1] <= '6' && s[1] > '0') {f[2] = 2;}else if ((s[0] == '0') || (s[0] != '1' && s[0] != '2' && s[1] == '0')) {return 0;}else {f[2] = 1;}// i从3开始循环,即从字符串第3位(s[2])开始循环,注意s[i-1]对应的是f[i](因为s标号比f小1)// 当第i个数和第i-1个数组成的数在11~19或21~26时,f[i] = f[i - 1] + f[i - 2];// 当两个数组成的数为10或20时,f[i] = f[i - 2];// 当个两个数组成的数不为10或20,且第i个数为0,则无法解码,直接返回结果为0// 其余情况,即组成01~09或26~99且第i个数不为0时,f[i] = f[i - 1];for (int i = 3; i <= n; i++) {if ((s[i - 2] == '1' && s[i - 1] != '0') || s[i - 2] == '2' && s[i - 1] <= '6' && s[i - 1] > '0') {f[i] = f[i - 1] + f[i - 2];}else if ((s[i - 2] == '1' || s[i - 2] == '2') && s[i - 1] == '0') {f[i] = f[i - 2];}else if (s[i - 2] != '1' && s[i - 2] != '2' && s[i - 1] == '0') {return 0;}else {f[i] = f[i - 1];}}return f[n];}};
简要题解:
本题是一道动态规划的问题。
先理清题意。本题的输入是一串数字字符串。从1~26的数字分别解码对应A~Z的字母,需要求出这串输入的数字串共可以有几种解码方法。
令f[i]表示“前i个数字共有几种解码方法”。需要处理的初始值有f[1]和f[2]两种。对于f[1],若第一位为0则无法解码,直接输出为0;其余情况下f[1] = 1。对于f[2],若前两位在11~19或21~26时,f[2]=2,即前两位可以有2种解码方法:为一个十位数或两个个位数;若第一位为0,或第二位为0且前两位不为10或20时,无法解码,直接输出0; 其余情况下均有f[2] = 1, 即前两位只有1种解码方法:需要将前两位拆成两个个位数.
处理完初始值,接着就可以列出转移方程。枚举i = 3 ~ n,注意字符串中s[i-1]对应的是转移方程中的f[i](因为s标号比f小1)。假设已经知道了f[i-1]的值,接着可以分析如下(这部分的思考方法有点类似本周做的台阶问题):
①当第i个数和第i-1个数组成的数在11~19或21~26时,f[i] = f[i - 1] + f[i - 2],即可以将第i个数和i-1个数看作两个1位数(此时对应f[i-1]的值),或是看作一个2位数(此时对应f[i-2]的值);
②当两个数组成的数为10或20时,f[i] = f[i - 2],此时只能将第i和i-1个数看作是一个2位数;
③当个两个数组成的数不为10或20,且第i个数为0,则无法解码,直接返回结果为0;
④其余情况,即组成01~09或26~99且第i个数不为0时,f[i] = f[i - 1],此时只能将第i和i-1个数看作是两个1位数。
这样枚举完之后,就可以计算出各个f[i]的值。
最后的结果即为f[n].
本题是一道稍微复杂的动态规划问题,做本题的关键是,在列出转移方程时,有非常多种不同的情况需要分别考虑。需要仔细认真地进行分类,防止漏掉其中某种转移方程的情况。
- 算法课第10周第3题——91. Decode Ways
- 第41题 Decode Ways
- 算法课第2周第2题——241. Different Ways to Add Parentheses
- 算法系列——Decode Ways
- leetcode刷题之旅——91. Decode Ways
- Leetcode——91. Decode Ways
- 【算法分析与设计】【第九周】91. Decode Ways
- 算法作业系列11——Decode Ways
- LeetCode —— Decode Ways
- LeetCode——Decode Ways
- leetcode——Decode Ways
- LeetCode91——Decode Ways
- leetcode笔记—Decode Ways
- Leetcode 91. Decode Ways&&639.Decode ways
- 算法课第10周第1题——70. Climbing Stairs
- 算法课第10周第2题——53. Maximum Subarray
- 算法课第1周第3题——38. Count and Say
- 算法课第3周第1题——113. Path Sum II
- HTTP请求
- 预处理
- 【qscoj】哗啦啦村的刁难(2)
- 剑指offer-面试题33-把数组排成最小的数
- CentOS7虚拟机无法联网,无法ping通网关
- 算法课第10周第3题——91. Decode Ways
- 记录配置Hadoop+zookeeper+Hbase的完整过程(三)
- 从零开始学递归与分治
- 域名系统DNS
- 第 1 章 数据与数据类型
- linux0.11内核 任务0 特权级 用户态 的疑问
- linux0.11 汇编 切换到任务0 的相关描述
- Android studio使用技巧(一:快捷键和断点调试)
- Java入门学习: Java对象自定义排序的实现