leetcode -- Decode Ways

本文介绍了一种使用动态规划解决消息解码问题的方法。对于由A到Z的字母映射到1到26的数字的问题,给定一个仅包含数字的编码信息,需计算其可能的解码方式总数。文章提供了详细的动态规划算法实现步骤。

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.

[解题思路]

本题一开始没有思路,上网搜索后发现与上楼梯那题类似

使用动态规划来解决问题,使用动态规划的目的是降低问题维度,通过解决子问题来来求解原问题

在求解子问题的过程中通过memoization来避免计算重复子问题,不过由于需要存储子问题的解,因而会有额外的空间消耗

令f(n)表示长度为n的输入解码方法,则有如下状态迁移方程:

f(n) = f(n-1) + f(n-2);                                             //s[n] is valid encoding char && s[n-1][n] is valid encoding char

f(n) = f(n-1);                                                          //s[n] is valid encoding char while s[n-1][n] is not valid encoding char 

f(n) = f(n-2);                                                          //s[n] is not valid encoding char && s[n-1][n] is valid encoding char

f(n) = 0;                                                                 //s[n] is not valid encoding char && s[n-1][n] is not valid encoding char

 1 private static int generate(String s) {
 2         int len = s.length();
 3         if (0 == len || s.charAt(0) == '0') {
 4             return 0;
 5         }
 6         int[] dp = new int[len + 1];
 7         dp[0] = 1;
 8         dp[1] = 1;
 9         for (int i = 2; i < len + 1; i++) {
10             char curChar = s.charAt(i - 1);
11             int curNum = curChar - '0';
12             // s[i] is not valid
13             if (curNum == 0) {
14                 String twoNum = s.substring(i - 2, i);
15                 // s[i-1][i] is valid
16                 if (Integer.parseInt(twoNum) <= 26
17                         && Integer.parseInt(twoNum) >= 10) {
18                     dp[i] = dp[i - 2];
19                 } else {
20                     dp[i] = 0;
21                 }
22             }
23             // s[i] is valid
24             else {
25                 String twoNum = s.substring(i - 2, i);
26                 // s[i-1][i] is valid
27                 if (Integer.parseInt(twoNum) <= 26
28                         && Integer.parseInt(twoNum) >= 10) {
29                     dp[i] = dp[i - 1] + dp[i - 2];
30                 } else {
31                     dp[i] = dp[i - 1];
32                 }
33             }
34         }
35 
36         return dp[len];
37     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值