【算法】LeetCode91.解码方法(类似爬楼梯)

2020-02-10

一条包含字母A-Z的消息通过以下方式进行了编码:

'A' -> 1
'B' -> 2
....
'Z' -> 26

给定一个只包含数字(包括0)的非空字符串,请计算解码方法的总数。
示例1:

输入:“12”
输出:2
解释:它可以解码为“AB”(1 2)或者“L”(12)

示例2:

输入:“226”
输出:3
解释:它可以解码为“BZ”(2 26),“VF”(22 6),或者“BBF”(2 2 6)

解题思路(动态规划)
首先举例子:例如计算22113的解码方法数量(从左往右)

  • 2有一种
  • 22有两种(2 2)(22)
  • 223有三种(2 2 3)(22 3)(2 23)
  • 2211有五种(2 2 1 1)(22 1 1)(2 21 1)(2 2 11)(22 11)
  • 22113有八种(2 2 1 1 3)(22 1 1 3)(2 21 1 3)(2 2 11 3)(2 2 1 13)(22 11 3)(2 21 13)(22 1 13)
    咦,好像发现了什么,对了,就是斐波那契!

但是如果碰见0的情况呢。
例如:02,909,这些情况结果都为0。

也就是说,状态转移方程不是单纯的f[i]=f[i-1]+f[i-2];

解法如下:
首先,建立dp数组,长度比输入字符串大1,dp[i]表示输入字符串中的开始位到i-1位的字串的解法数量。
1.首先判断第i位,检查是否为‘0’,若是则将dp[i]赋值为0,如不是,则dp[i]=dp[i-1];
2.再判断第i位和i-1位,检查该两位是否小于“26”,如果小于,则dp+=dp[i-2];否则不操作。
3.遍历完后返回dp[dp.length-1];

再用22113为例,在对最后一位分析时,numDecodings("22113") = numDecodings("2211")+numDecodings("221")

代码如下:

	public int numDecodings(String s) {
		if(s == null || s.charAt(0)=='0'){
			return 0;
		}
		int[] dp = new int[s.length()+1];
		dp[0] = 1;
		for(int i = 1; i < dp.length; i++){
			dp[i] = (s.charAt(i-1)=='0'?0:dp[i-1]);
			if(i >= 2 && (s.charAt(i-2) == '1' || (s.charAt(i-2) == '2' && s.charAt(i-1) <= '6'))){
				dp[i] += dp[i-2];
			}
		}
		return dp[dp.length-1];
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值