leetcode题目 91. 解码方法

题目

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

‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
注意:可能存在不能解码的情况,如’00’

示例

示例 1:

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

示例 2:

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

思路

递推
我们发现dp[n]的解码方法数只与dp[n-1]和dp[n-2]有关(dp[i]代表到第i位为止的解码种数)
1、当s.charAt(i)=='0’时,说明第i位不能单独解码,所以dp[i]=0,否则dp[i]=dp[i-1]
2、当i-1位与i位组成的数在1~26,说明[i-1,i]可以组成合法的编码,所以dp[i]=dp[i]+dp[i-2],否则不改变
(注意:我写的步骤是有顺序的,不然公式就要发生改变,但思路理解,怎么改你都应该会写)

(其实递归也是能做的,但超时了,所以就不放上来了)

看过上面过程,其实我们能发现我们只需要保存dp[i-2],dp[i-1],dp[i]的值,所以我们只需要三个变量进行递推即可。

代码

public class problem91 {
	/*
	 * 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 …… 'Z' -> 26
	 * 
	 * 给定一个只包含数字的非空字符串,请计算解码方法的总数。
	 * 
	 * 如12可解析为1、2或12
	 * 
	 */
	public int numDecodings(String s) {
		// 特判
		if (s.length() == 0)
			return 0;
		if (s.charAt(0) == '0')
			return 0;
		if (s.length() == 1)
			return 1;

		//// 保存dp[n - 2], dp[n - 1], dp[n](dp[i]表示到第i个字符为止的解码方式)
		int[] dp = { 0, 1, 1 };

		for (int i = 1; i < s.length(); i++) {
			dp[0] = dp[1];
			dp[1] = dp[2];

			if (s.charAt(i) == '0')
				dp[2] = 0;

			//判断第n-1和第n位是否会组成一个正确的编码
			int tmp = (s.charAt(i - 1) - '0') * 10 + s.charAt(i) - '0';
			if (tmp > 9 && tmp < 27)
				dp[2] = dp[2] + dp[0];
			// 出现'00'时,提前返回,节约时间
			else if (tmp == 0)
				return 0;
		}

		return dp[2];
	}

	public static void main(String[] args) {
		problem91 pro = new problem91();
		System.out.println(pro.numDecodings("12"));

	}
}
发布了36 篇原创文章 · 获赞 0 · 访问量 489

猜你喜欢

转载自blog.csdn.net/qq_36360463/article/details/104255100