算法---把数字翻译成字符串

题目要求:
给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。

参考至该作者

自上而下,从最大的问题开始,递归 :
                     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
有很多子问题被多次计算,比如258被翻译成几种这个子问题就被计算了两次。

自下而上,动态规划,从最小的问题开始 :
f(r)表示以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);
其中,如果r-2,r-1能够翻译成字符,则g(r-2,r-1)=1,否则为0。
因此,对于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

上代码:

public class TranslateNumbersToStrings {

	public static int getTranslationCount(int number){
		
		if(number<0)
			return 0;
		
		if(number==1)
			return 1;
		return getTranslationCount(String.valueOf(number));
	}
	//动态规划,从右往左算
	// f(i) = f(i+1)+f(i+2)*g(i,i+1),其中g(i,i+1)用来判断两位是否满足0~25
	private static int getTranslationCount(String str) {
		int f1 = 0;
		int f2 = 1;
		//判断两位数是否是0=<g<=25
		int g = 0;
		/*
		 * f(5) = f1 = 0;
		 * f(4) = f2 = 1;
		 * f(3) = f(4) + f(5)*g(3,4)
		 * f(2) = f(3) + f(4)
		 * */
		for(int i = str.length()-2;i >= 0;i--)
		{
			g = (str.charAt(i)-'0')*10 + (str.charAt(i+1)-'0');
			if((0<=g)&&(g<=25))
			{
				int temp = f2;
				f2 = f1 + f2;
				f1 = temp;		
			}
			else{
				f1 = f2;
			}
		}
		
		return f2;
	}
	public static void main(String[] args) {
		System.out.println(getTranslationCount(12258));
		System.out.println(getTranslationCount(50008));
	}
}

此外,在剑指Offer上面的解析中对g(i,i+1)的解释是10<=g<=25,我觉得不正确,比如101中的01不止代表一种,我觉得可以分开为0,1和01这两种情况分别对应ab和b,因为题目中的要求0是有代表字母a的。不知道有没大佬能给我解释一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值