46_TranslateNumbersToStrings

package pers.lyt.java;

//题目 
//	给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成"a",1翻译成"b",……,
//11翻译成"l",……,25翻译成"z"。一个数字可能有多个翻译。例如12258有5种不同的翻译,
//它们分别"bccfi", "bwfi", "bczi", "mcfi" 和"mzi" 。请编程实现一个函数用来计算一个
//数字有多少种不同的翻译方法。
//思路
//	看到题目,很容易想到使用递归:用f(i)来表示从第i位开始的不同翻译数目,可以得到有:
//f(i)=f(i+1)+g(i,i+1)*f(i+2)。i和i+1位数字拼起来在10~25范围内时g(i,i+1)的值为1,
//否则为0。
//但是存在重复的子问题,所以递归并非最佳方法,我们从数字的末尾开始计算f(i),自下而上
//解决问题,就可以消除重复的子问题了。先算f(len-1),f(len-2),再根据公式
//f(i)=f(i+1)+g(i,i+1)*f(i+2)往前逐步推导到f(0),这就是最终要求的结果。
public class Offer46_TranslateNumbersToStrings {
	public int getTranslationCount(int number) {
		if (number < 0)
			return 0;

		String sNumber = String.valueOf(number);
		int len = sNumber.length();
		int[] counts = new int[len];
		// 1.数组最后位置 1
		counts[len - 1] = 1;
		for (int i = len - 2; i >= 0; i--) {
			// 2.先将后面元素值copy到当前数组位置
			counts[i] = counts[i + 1];
			// 3.0 判断后两个数值是否在范围内
			if (canBeTrans(sNumber, i)) {
				// 3.1 如果是数组倒数第二个元素,当前元素 + 1
				if (i == len - 2) {
					counts[i] += 1;
				} else {
					// 3.2 否则当前元素的后后一个元素值加到当前数组元素
					counts[i] += counts[i + 2];
				}
			}
		}
		return counts[0];
	}

	private boolean canBeTrans(String sNumber, int i) {
		int a = sNumber.charAt(i) - '0';
		int b = sNumber.charAt(i + 1) - '0';
		int convert = a * 10 + b;
		if (convert >= 10 && convert <= 25) //合并后在10到25范围内才能看成一个字母
			return true;
		return false;
	}

	public static void main(String[] args) {
		Offer46_TranslateNumbersToStrings demo = new Offer46_TranslateNumbersToStrings();
		System.out.println(demo.getTranslationCount(0) == 1);
		System.out.println(demo.getTranslationCount(10) == 2);
		System.out.println(demo.getTranslationCount(12258) == 5);
		System.out.println(demo.getTranslationCount(101) == 2); //01 只能翻译为a,b
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值