LeetCode91:解码方式(动态规划)

问题描述:
A message containing letters from A-Z is being encoded to numbers using the following mapping:

‘A’ -> 1
‘B’ -> 2

‘Z’ -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: “12”
Output: 2
Explanation: It could be decoded as “AB” (1 2) or “L” (12).
Example 2:

Input: “226”
Output: 3
Explanation: It could be decoded as “BZ” (2 26), “VF” (22 6), or “BBF” (2 2 6).

**解题思路:**动态规划(使用递归会超时)
这题有点像跳台阶,最后面那个字符i可以单独一个,也可以和前面的字符i-1合并到一起,这个有点像最后一个台阶跳一步还是两步。跳一步的话是在DP[i-1]的基础上跳,跳两步的话是在DP[i-2]的基础上跳,因此跳台阶那题的递推公式为DP[i]=DP[i-1]+DP[i-2]。而这题的递归公式也是类似的。

举个栗子
当前给定的字符串是:“1226”
当前位置:0,则可能的编码为1
当前位置:1,则可能的编码为1-2,12
当前位置:2,则可能的编码为1-2-2,12-2,1-22
当前位置:3,则可能的编码为1-2-2-612-2-612-261-22-61-2-26(这里单独一位就是在位置2的基础上加上6,合并就是在位置1的基础上加上26)

解释:若当前在位置1,则当前位置的字符’2’可以选择与前面那个字符合并或者自己单独一位(这就类似于跳两步和跳一步),如果是自己单独一位,那么DP[i]=DP[i-1]。如果是要和前面一位合并,DP[i]=DP[i-2]。若两种情况都是满足的,那么DP[i]=DP[i-1]+DP[i-2]。

在进行DP的时候还需要考虑几种特殊的情况:
(1)当前位置i的字符为’0’,那么不能考虑单独一位,只能考虑合并
(2)当前位置和前面的位置合并的时候>‘26’,那么只能考虑单独一位

代码:

public int DP(String s){
        if (s.length()==0){
            return 0;
        }
        /**
         * 字符串长度为1的情况
         */
        int[] dp=new int[s.length()];
        dp[0]=s.charAt(0)=='0'?0:1;
        if (s.length()==1){
            return dp[0];
        }
        /**
         * 字符串长度为2,第一种是拆分的情况,第二种是合并的情况
         */
        dp[1]+=s.charAt(0)>'0' && s.charAt(1)>'0'?1:0;//第一种是独立的情况,有一个为0,就不能拆分了1-0这样子
        dp[1]+=(s.charAt(0)=='1'||s.charAt(0)=='2'&&s.charAt(1)<='6'?1:0);//这一种是合并的情况
        for (int i=2;i

你可能感兴趣的:(算法,LeetCode算法)