【剑指offer】48.把数字翻译成字符串
总目录:
1.问题描述
有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。
现在给一串数字,返回有多少种可能的译码结果
数据范围:字符串长度满足 0<n≤90
进阶:空间复杂度 O(n),时间复杂度 O(n)
2.问题分析
1动态规划+记忆搜索
类似下楼梯问题,但是规则较为复杂,注意单个字符、两个字符是否可以合法翻译的规则
3.代码实例
动态规划+记忆搜索
1 class Solution { 2 public: 3 /** 4 * 解码 5 * @param nums string字符串 数字串 6 * @return int整型 7 */ 8 bool CanBeSingle(string nums, int end) { 9 if (end < 0 || end >= nums.size()) { 10 return false; 11 } 12 13 if (nums[end] < '1' || nums[end] > '9') { 14 return false; 15 } 16 17 return true; 18 } 19 bool CanBeSum(string nums, int end) { 20 //生于长度不够合并 21 if (end < 1) { 22 return false; 23 } 24 25 //超出编码范围 26 if (nums[end - 1] < '1' 27 || nums[end - 1] > '2' 28 || (nums[end - 1] == '2' && nums[end] > '6')) { 29 return false; 30 } 31 32 return true; 33 } 34 35 int getDp(string nums, int curId) { 36 if (curId < 0) { 37 return 0; 38 } 39 40 //记忆搜索 41 if (dp.size() > curId) { 42 return dp[curId]; 43 } 44 45 //新计算值 46 if (curId == 0) { 47 return CanBeSingle(nums, curId) ? 1 : 0; 48 } 49 if (curId == 1) { 50 if (CanBeSingle(nums, 0) && CanBeSingle(nums, 1)) { 51 return 1 + (CanBeSum(nums, curId) ? 1 : 0); 52 } else { 53 return CanBeSum(nums, curId) ? 1 : 0; 54 } 55 } 56 //dp1 57 int dp1 = CanBeSingle(nums, curId) ? getDp(nums, curId - 1) : 0; 58 59 //dp2 60 int dp2 = CanBeSum(nums, curId) ? getDp(nums, curId - 2) : 0; 61 62 return dp1 + dp2; 63 } 64 vector<int> dp; 65 int solve(string nums) { 66 int strLen = nums.size(); 67 if (strLen < 1) { 68 return 0; 69 } 70 71 //建立dp表 72 for (int i = 0; i < strLen; i++) { 73 dp.push_back(getDp(nums, i)); 74 } 75 76 return getDp(nums, strLen - 1); 77 } 78 };