题目分析:
- 对给定的一串数字,将其解码成对应的英文字母
解题思路:
递归实现(超时)
1)根据当前字符串中起始字符是否为1或起始字符为2且下一字符是否小于6进行不同的的递归;
2)每次递归,字符串长度相应的减小,最后根据当前字符串的长度是否为0,1或者字符串为‘0’为递归的终止条件。
动态规划实现
1)设置一个数组dp[n+2]用来存放遍历到每个字符时,对应的编码个数,并将对应数组中元素初始化为1;
2)遍历字符串,对于遍历到的第i个字符,其编码方式分为以下两种情况:dp[i+1] = dp[i],或者dp[i+1] +=dp[i] + dp[i-1];
3)依据上面递归式进行编程求解即可。
注意:遍历的方式从后向前遍历实现。
实现程序
class Solution { public: //第一种方法:递归求解(超时) int numDecodings1(string s) { // 如果字符串s为空或者当前字符为'0'返回0 if (s.size() == 0 || s[0] == '0') return 0; // 如果当前字符串长度为1,或者当前字符串 if (s.size() == 1 && s[0] != '0') return 1; int fix = s.size() == 2 ? 1 : 0; if (s[0] == '1' || (s[0] == '2' && s[1] <= '6')) return numDecodings(s.substr(1)) + numDecodings(s.substr(2)) + fix; return numDecodings(s.substr(1)); } //第二种方法:动态规划实现 int numDecodings(string s) { if (s.size() == 0) return 0; //初始化dp,多出两个占位符,防止程序判断超过size // 注意,从后向前遍历实现 vector<int> dp(s.size() + 2, 1); for (int i = s.size() - 1; i >= 0; i--) { //一个字符情况 if (s[i] == '0') dp[i] = 0; // dp[i]至少和dp[i+1]一样 else dp[i] = dp[i + 1]; // dp[i] = dp[i+1] + dp[i+2]情况 if (i + 1 < s.size() && ((s[i] == '1' || (s[i] == '2' && s[i + 1] <= '6')))) dp[i] += dp[i + 2]; } // 返回最终结果 return dp[0]; } };