Decode-Ways 解码方法

题目描述:

有一个消息包含A-Z通过以下规则编码

'A' -> 1
'B' -> 2
...
'Z' -> 26

现在给你一个加密过后的消息,问有几种解码的方式

样例

样例 1:

输入: "12"
输出: 2
解释: 它可以被解码为 AB (1 2) 或 L (12).

样例 2:

输入: "10"
输出: 1

注意事项

我们不能解码空串,因此若消息为空,你应该返回0。
消息的长度 n≤100

 

思路:

划分型动态规划解题,这里我们需要从最后一个数字和最后两个数字开始着手分析最后一步,如果最后一个数字是1~9,那么最后一个数字的解码方式就依赖于前n - 1个数字的解码方式(这里就是累加),再如果最后一个数字可以跟倒数第二个数字能组成一个大于10且小于等于26的正整数的话,那么最后一个数字对应的解码方式就要在原来的基础之上再累加前n - 2个数字的解码方式并存储在了最后一个数字的dp数组中,这样才能最终得到前n个数字有多少种的解码方式(体现了划分的思想)

 

动态规划算法四步走:

1、分析最后一步是如何到达的

2、确定初始条件和边界值

3、列出状态转移方程

4、根据题目意思求解并返回最终需要的结果

 

AC代码:

复制代码
 1 public class Solution {
 2     /**
 3      * @param s: a string,  encoded message
 4      * @return: an integer, the number of ways decoding
 5      */
 6     public int numDecodings(String s) {
 7         char[] c = s.toCharArray();
 8         int n = c.length;
 9         
10         // 判空,单独一个空串是没有解压方式的,而后面dp[0] = 1是因为后面一定有数字
11         // 只要有1个数字和空串组合那也是1种方式,所以才会初始化为1,而空串本身后面
12         // 就已经没有任何数字能被解压回去了,因此return 0 是有一定道理的。
13         if (n == 0) {
14             return 0;
15         }
16 
17         // write your code here
18         // 1、最后一步:如果只有一个数字,我们直接判断该数字是否在1~9范围之间,有就返回1,反之返回0
19         // 如果长度 > 1的话,我们就可以判断最后一个数字是否在1~9范围之间,并且还需要查看其与前一个数字
20         // 组成起来能否解码为一个字母,即10~26范围
21         // 要值得注意的是,像01这种是不能作为整体转为字母的,
22         // 如果能组成就看前i - 2个字母能组成有多少种方式
23         // 如果不能组成则只需看前i - 1个字母组成能有多少种方式
24         
25         // n + 1,划分型动态规划结合序列型动态规划,因为0个数字也是能组成一种的,这样一来初始化就很方便
26         int[] dp = new int[n + 1];
27 
28         // 初始化
29         dp[0] = 1;
30 
31         // 转移方程,这里考虑的是从前1个字母到前n个字母
32         for (int i = 1; i <= n; i++) {
33             // 默认一开始为0,因为要取决于前面i - 1和i - 2的情况
34             dp[i] = 0;
35             // 看当前一个数字是否在1~9范围之内,这里的下标不要忘了 - 1
36             int num = c[i - 1] - '0';
37             if (num >= 1 && num <= 9) {
38                 dp[i] += dp[i - 1];
39             }
40             if (i - 2 >= 0) {
41                 // 至少两个字母
42                 // 下面就需要判断当前前i个数字的最后两个数字能否解压为一个字母
43                 int temp = (c[i - 2] - '0') * 10 + (c[i - 1] - '0');
44                 if (temp >= 10 && temp <= 26) {
45                     dp[i] += dp[i - 2];
46                 }
47             }
48         }
49 
50         // 最后返回的是前n个字母的解码方式个数
51         return dp[n];
52     }
53 }
复制代码

 

posted @   没有你哪有我  阅读(79)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示