题目描述
面试题46:给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。
题目分析
见到题目第一反应是递归,然而…写了半天也没写出来。剑指offer的思路也是递归,但是用循环实现。其实本质上来说,这是一道考察动态规划的题目。假设dp[i]表示位置i之前(不包括位置i)总共有多少种翻译方法,则状态方程如下:
当s[i-2:i]这两个字符是10-25时,比如21,此时有两种翻译方式,所以dp[i] = dp[i-1] + dp[i-2]。
当s[i-2:i]这两个字符不在上述范围,比如39,比如00,此时只有一种翻译方式,所以dp[i] = dp[i-1]。
注意初始化时,dp[0] = 1, dp[1] = 1.
注意申请dp的时候,多申请一个数。
dp数组的最开始的数相等于一个““辅助”数,其值为1,
class Solution {
public:
int numDecodings(string s) {
if (s.empty()||s[0]=='0')
return 0;
//int* dp = new int[s.size + 1];
vector<int> dp(s.size()+1,0); //初始化为s.size()+1个零
dp[0] = 1;
dp[1] = 1;
for (int i=2;i<=s.size();i++){
//if (s[i-2]=='1' || (s[i-2]=='2' && s[i-1]<='6'))
if('10' <= s.substr[i-2,2] <= '25')
dp[i] = dp[i-1] + dp[i-2];
else
dp[i] = dp[i-1];
}
return dp.back(); //v.back(),返回v的最后一个元素
//delete[] dp;
}
};
c++中str.substr的用法
substr有2种用法:
假设:string s = “0123456789”;
string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = “56789”
string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = “567”