[leetcode] 91. Decode Ways 解题报告

来源:互联网 发布:iphone设置网络权限 编辑:程序博客网 时间:2024/06/06 00:59

题目链接:https://leetcode.com/problems/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.


思路:看到这种类型的题目第一个感觉就是dp,然后接下来就是寻找能否将问题转化为子问题,即子结构。

申请一个数组dp,dp[i]代表S[0, i-1]的子串有多少种编码方式

考虑到在当前字符可以单独编码,也可以两个字符一起编码,则很容易想到每一位会有两种选择:

1. 如果当前字符单独编码,则这种情况编码方式有dp[i-1]种,但是注意到‘0’不可以单独编码

2. 如果当前字符和之前字符一起编码,则这种情况下有dp[i-2]中编码方式,同样两个字符一起编码也是有限制的,编码后要在1 - 26之间

因此可以得出一维动归的状态转移方程为dp[i] = dp[i-1] + dp[i-2];

另外如果首字母为0,则无法编码.时间复杂度为O(n),空间复杂度为O(n)


还可以用DFS记忆化搜索, 好像只要是带记忆话搜索的, 大多都可以动归来解决.

代码如下:

class Solution {public:    int numDecodings(string s) {        if(s.size() ==0 || s[0]=='0') return 0;        int len = s.size();        vector<int> dp(len+1, 0);        dp[1] = dp[0] = 1;        for(int i = 1; i < len; i++)        {            if(s[i] != '0') dp[i+1] += dp[i];            int val = stoi(s.substr(i-1,2));            if(val >= 10 && val <= 26) dp[i+1] += dp[i-1];        }        return dp[len];    }};

class Solution {public:    int DFS(string s, int k, unordered_map<int, int>& hash)    {        if(k == s.size()) return 1;        if(s[k] == '0') return 0;        if(hash.count(k)) return hash[k];        int ans = DFS(s, k+1, hash);        if(k+1<s.size() && stoi(s.substr(k,2)) <= 26)             ans += DFS(s, k+2, hash);        hash[k] = ans;        return ans;    }        int numDecodings(string s) {        if(s.size() == 0) return 0;        unordered_map<int, int> hash;        return DFS(s, 0, hash);    }};


0 0
原创粉丝点击