把数字翻译成字符串

题目:

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”
,……,25 翻译成 “z”。一个数字可能有多个翻译。
请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”
提示:
0 <= num < 231

分析

核心思想:
自上而下,从最大的问题开始,递归 :
12258
/
b+2258 m+258
/ \ /
bc+258 bw+58 mc+58 mz+8
/ \ \ \
bcc+58 bcz+8 bwf+8 mcf+8 mzi
/ \ \
bccf+8 bczi bwfi mcfi
/
bccfi

自下而上,动态规划,从最小的问题开始 :
f®表示以r为开始(r最小取0)到最右端所组成的数字能够翻译成字符串的种数。对于长度为n的数字,f(n)=0,f(n-1)=1,
求f(0)。
递推公式为 f(r-2) = f(r-1)+g(r-2,r-1)*f®;
其中,如果r-2,r-1能够翻译成字符,则g(r-2,r-1)=1,否则为0。通俗来说如果前一个和后一个相加在10到25之间说明
有两种可能f(n)=f(n-1)+f(n-2),若不在则f(n) = f(n-1)

因此,对于12258:
f(5) = 0
f(4) = 1
f(3) = f(4)+0 = 1
f(2) = f(3)+f(4) = 2
f(1) = f(2)+f(3) = 3
f(0) = f(1)+f(2) = 5

附注:
1.分析其是否为DP问题。两个条件:1.最优子结构;2.重复子问题。分析一下,以12258为例,将1和2258分离成
两部分,先翻译1,在翻译2258,明显2258是在1的基础上在进行翻译,以此类推,满足上述条件,为DP问题。
2.从最小结构入手,然后一步步扩大范围,直至求出结果。此题中可以理解为从后即 f(n),f(n-1),最小子结构
入手,如果从前到后则不然。

#include<vector>

using namespace std;

class MyClass
{
public:
	int translateNum(int num){		
		if (num < 10){
			return 1;
		}

		vector<int> st;
		while (num != 0){
			int tmp = num % 10;
			st.push_back(tmp);
			num = num / 10;
		}

		reverse(st.begin(), st.end());
		int n = st.size();
		int* res = new int[n];
		res[n - 1] = 1;
		for (int i = n - 2; i >= 0; --i){
			int sum = st[i] * 10 + st[i + 1];
			if (sum >= 10 && sum <= 25){
				if (i == n - 2){
					res[i] = res[i + 1] + 1;
				}
				else
				{
					res[i] = res[i + 1] + res[i + 2];
				}
			}
			else{
				res[i] = res[i + 1];
			}
		}
		return res[0];
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值