【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
剑指Offer-46:把数字翻译成字符串
题目:
给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成“a”,1翻译成“b”,……,11翻译成“1”,……,25翻译成“z”。一个数字可能有多个翻译。例如:12258有5种不同的翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
/*
问题:把数字翻译成字符串
方法:动态规划
将数字number转成字符串s,方便引用各位
dp[i]表示以s[0~i]的数字翻译成字符串的方法数
则有dp[i] = dp[i - 1] + g*dp[i - 2] (当s[i-1,i]能组合在一起翻译成有效字符时,g=1,否则g=0)
上式右边分别对应两种分隔方法:
s[0~i-1] + s[i](共dp[i-1]种)
s[0~i-2] + s[i-1,i](如果g=1,该分隔有效,共dp[i-2]种)
本题类似:climb stairs
*/
using namespace std;
#include <iostream>
#include <vector>
#include <string>
int translation(int number)
{
if (number<0) return 0;
string s = to_string(number);//把数字转成字符串,方便引用各位数字
int n = s.size();
if (n == 1) return 1;//因为通项公式中最少须有两个初始值
vector<int> dp(n);//一般dp中序号与实际的序号对应起来,决定分配n空间还是n+1空间
dp[0] = 1; //递推公式需要两个初值
int temp = (s[0] - '0')*10 + s[1] - '0'; //构造组合数
if (temp>=10 && temp<=25)
dp[1] = 2;
else
dp[1] = 1;
int g = 0;
for (int i = 2; i <= n-1; i++)
{
int temp = (s[i-1] - '0')*10 + s[i] - '0';
if (temp>=10 && temp<=25)
g = 1;
else
g = 0;
dp[i] = dp[i - 1] + g*dp[i - 2]; //假设dp[0]=1,则从dp[2]开始满足通项公式
}
return dp[n-1];
}