91. Decode Ways

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.

分析:需要注意的是,如果序列中有不能匹配的0,那么解码方法是0,比如序列012 、100(第二个0可以和1组成10,第三个0不能匹配)。递归的解法很容易,但是大集合会超时。转换成动态规划的方法,假设dp[i]表示序列 s[0...i-1]的解码数目,动态规划方程如下:                                                                                                                                                           

  • 初始条件:dp[0] = 1, dp[1] = (s[0] == '0') ? 0 : 1
  • dp[i] = ( s[i-1] == 0 ? 0 : dp[i-1] ) + ( s[i-2,i-1]可以表示字母 ? dp[i-2] : 0 ), 其中第一个分量是把s[0...i-1]末尾一个数字当做一个字母来考虑,第二个分量是把s[0...i-1]末尾两个数字当做一个字母来考虑

代码如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution { 
public
    int numDecodings(string s) { 
        // IMPORTANT: Please reset any member data you declared, as 
        // the same Solution instance will be reused for each test case. 
        //注意处理字符串中字符为0的情况 
        int len = s.size(); 
        if(len == 0)return 0
        int dp[len+1];//dp[i]表示s[0...i-1]的解码方法数目 
        dp[0] = 1
        if(s[0] != '0')dp[1] = 1
        else dp[1] = 0
        for(int i = 2; i <= len; i++) 
        
            if(s[i-1] != '0'
                dp[i] = dp[i-1]; 
            else dp[i] = 0
            if(s[i-2] == '1' || (s[i-2] == '2' && s[i-1] <= '6')) 
                dp[i] += dp[i-2]; 
        
        return dp[len]; 
    
};

 2、带标记的递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Solution {
    public int numDecodings(String s) {
        if(s == null || s.isEmpty())
            return 0;
 
        return findTotal(s,0);
    }
 
    Map<Integer,Integer> result = new HashMap<>();
    public int findTotal(String s,int index){
        if(index == s.length()){
            return 1;
        }
        if(s.charAt(index) == '0'){
            return 0;
        }
        int dou;
        Integer temp1 = result.get(index+1);
        if(temp1 == null){
            temp1 = findTotal(s,index+1);
            result.put(index+1,temp1);
        }
        if(index + 1 < s.length() && (dou = Integer.valueOf(s.substring(index,index+2)))<= 26&& dou > 0){  // 可以跳两步,
            Integer temp2 = result.get(index+2);
            if(temp2 == null){
                temp2 = findTotal(s,index+2);
                result.put(index+2,temp1);
            }
            return temp1 + temp2;
        }else// 只能跳一步
            return temp1;
        }
    }
}

 

posted @   月是故乡明95  阅读(131)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何调试 malloc 的底层源码
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
阅读排行:
· Apifox不支持离线,Apipost可以!
· 零经验选手,Compose 一天开发一款小游戏!
· 历时 8 年,我冲上开源榜前 8 了!
· Trae 开发工具与使用技巧
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示