《leetcode》decode-ways

题目:

给定一串仅包含数字的加密字符串,假设加密规则已知,如下所示:A加密为1,B加密为2,如此类推,直到Z加密为26,问有多少种解码的方式。(如:12——2种【1,2】或【12】,56——1种【5,6】)

解题思路:

先把只有一个数字和两个数字的字符串的解码总数求出来,因为后面的每一位与其前第一和前第二位解码总数相关联。
例如:12——2种【1,2】或【12】。
121——1种【1,21】能组合且组合,与其前第二位解码总数一样。在12的后面加上1,1能与前第一位2组合,所以组合在一起变成21,其解码总数即与1的解码总数是一样的,等于在1的所有解码方式后面加了一个21而已。
121——2种【1,2,1】或【12,1】能组合但是不组合,与其前第一位解码总数一样。在12的后面加上1,1能与前第一位2组合,但是不组合在一起,其解码总数即与12的解码总数是一样的,等于在12的所有解码方式后面加了一个1而已。
也有不能组合的情况,如:
127,7不能与2组合,因为组合就变成了27>26。所以它与其前第一位解码总数一样。
要特别注意有0的情况,特殊对待,如160,其解码总数为0。

代码:

public int numDecodings(String s) {
		if (s == null || s.length() == 0 || s.charAt(0) == '0')
			return 0;
		int[] dp = new int[s.length()];

		if (s.charAt(0) == '0')// 把dp[0]求出来
			dp[0] = 0;
		else
			dp[0] = 1;

		if (s.length() > 1 && s.charAt(1) == '0' && s.charAt(0) >= '3')// 把dp[1]求出来
			return 0;
		if (s.length() > 1 && s.charAt(0) == '0')
			dp[1] = 0;
		if (s.length() > 1
				&& ((s.charAt(0) == '1' && s.charAt(1) == '0')
						|| (s.charAt(0) == '2' && s.charAt(1) == '0')
						|| (s.charAt(0) == '2' && s.charAt(1) > '6') || s
						.charAt(0) >= '3'))
			dp[1] = 1;
		else if (s.length() > 1)
			dp[1] = 2;

		for (int i = 2; i < s.length(); i++) {
			// 能组合
			if (s.charAt(i - 1) == '1'
					|| (s.charAt(i - 1) == '2' && s.charAt(i) <= '6'))// 能组合且组合在一起
				dp[i] = dp[i - 2];
			if (s.charAt(i) != '0'
					&& (s.charAt(i - 1) == '1' || (s.charAt(i - 1) == '2' && s
							.charAt(i) <= '6')))// 能组合但不组合在一起
				dp[i] += dp[i - 1];

			// 不能组合
			if (s.charAt(i) == '0'
					&& !(s.charAt(i - 1) == '1' || (s.charAt(i - 1) == '2' && s
							.charAt(i) <= '6')))
				return 0;
			if (s.charAt(i) != '0'
					&& !(s.charAt(i - 1) == '1' || (s.charAt(i - 1) == '2' && s
							.charAt(i) <= '6')))
				dp[i] = dp[i - 1];
		}
		return dp[s.length() - 1];
	}

猜你喜欢

转载自blog.csdn.net/weixin_44997483/article/details/90218444