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

来源:互联网 发布:陈霸先 知乎 编辑:程序博客网 时间:2024/06/06 02:10

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

动态规划基础训练。

  • Decode Ways
    • 题目大意
    • 思路
      • 最后两位分析
      • 状态转移式
    • 解题代码
    • 时间复杂度

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 > 26 state[i] = state[i-1] 11 <= XX <= 26 and XX != 20 state[i] = state[i-1] + state[i-2] 0 < XX <= 9 state[i] = state[i-1] XX == 10 or XX == 20 state[i] = state[i-2] XX == 00 state[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)


原创粉丝点击