【算法分析与设计】【第九周】91. Decode Ways

题目来源:91:https://leetcode.com/problems/decode-ways/description/

动态规划基础训练。

91. Decode Ways

题目大意

将大写字母串加密,有如下映射:

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

‘Z’ -> 26

现给出一串加密过的数字串,要求求出该串能解密出的不同大写字母串的数目。


“12”-> “AB” (1 2) or “L” (12).
ans:2

思路

动态规划要求把问题缩小为子问题。我们不妨假设长度为N的数字串,前(N-2)位已经解密完毕,那么此时我们只要考虑最后两位。
这里有一个疑问:按照动态规划的思想,为什么不是考虑最后一位而要最后两位呢?其实题目中给的例子已经给了很大的提示。分析完自然就明白子问题为什么要这样划分。

最后两位分析

考虑最后两位,最后两位XX无非以下几种情况:
(1)XX > 26 ;只有一种解法(例如99,只能解码为9 9->”II”)。
(2)11 <= XX <= 26 and XX != 20;两种解法(参考题目大意所述例子)。
(3)0 < XX <= 9,即00 < XX <= 09(这里不表示8进制);只有一种解法(十位上的0无法解码)。
(4)XX == 10 or XX == 20;只有一种解法(个位上的0无法解码)。
(5)XX == 00 ;无法解码。(这是被我遗忘的一种可能性,边界情况需要格外注意)。

状态转移式

考虑清楚以上几种状态后,写出状态转移式:
(1)state[i] = state[i-1];
(2)state[i] = state[i-1] + state[i-2];
(3)state[i] = state[i-1];
(4)state[i] = state[i-2];
(5)state[i] = 0;

画个表格整理一下思路:

最后两位的取值范围状态转移式
XX > 26state[i] = state[i-1]
11 <= XX <= 26 and XX != 20state[i] = state[i-1] + state[i-2]
0 < XX <= 9state[i] = state[i-1]
XX == 10 or XX == 20state[i] = state[i-2]
XX == 00state[i] = 0

解题代码

public:
  int numDecodings(string s) {
    int size = s.length();
    if(s == "" || size == 0 || s[0] =='0') return 0;
    int state1 = 1;   // state[i-2]
    int state2 = 1;   // state[i-1]
    int state3 = 1;   // state[i]
    for (int i = 1; i < size; i++) {
      if (s[i] == '0') {
        // 情况4,只有一种解法(个位上的0无法解码)
        if (s[i-1] == '1' || s[i-1] == '2') state3 = state1;
        else return 0;
      } else {  
        // 情况1或3,只有一种解法
        if(s[i-1] == '0' || s[i-1] >= '3') state3 = state2;
        else {     
          // 情况1,只有一种解法
          if(s[i-1] == '2' && s[i] >= '7' && s[i] <= '9') state3 = state2;  
          // 情况2,两种解法
          else state3 = state1+state2;
        }
      } 
      state1 = state2; 
      state2 = state3; 
    }
    return state2;
  }
};

时间复杂度

O(n)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值