题目
思路
此题可用动态规划求解
- 定义状态:dp[i]表示第i位数结尾时,有几种翻译方式
- 返回值:返回dp[nums.length]
- 状态转移方程
- 如果第i位数不可以与前面第i-1位数连着翻译,则第i位数只有一种翻译方式,如58中的8只能翻译成i,那么dp[i]=dp[i-1]
- 如果第i位数可以与前面第i-1位数连着翻译,则第i位数有两种翻译方式,如12中的2,可以翻译成c,此时dp[i]=dp[i-1];也可以12连起来翻译成m,此时dp[i]=dp[i-2]。所以dp[i]=dp[i-1]+dp[i-2]
- 初始值:dp[1]=1。当第二位数可以与第一位数合起来翻译时,dp[2]=2;否则dp[2]=1。我们不妨设dp[0]=1,好统一处理。
遍历数字:我们可以先将数字转化成字符串,再遍历字符串
空间优化:
1.转成字符串需要占用内存。而数字取余数是很方便的,我们可以将算法从后往前取余数遍历
2.由于dp[i]只与dp[i-1]、dp[i-2]有关,可以用p、q分别表示dp[i-2],dp[i-1]与dp[i]
代码
class Solution {
public int translateNum(int num) {
int p=1,q=1;//p表示dp[i-2],q表示dp[i-1]和dp[i]
int m,n;//记录当前与前一个余数
m=num%10;
while(num!=0){
num=num/10;
n=num%10;
int tmp=q;
if(n*10+m>m && n*10+m<=25) q=p+q;
p=tmp;
m=n;
}
return q;
}
}