LeetCode 91&&639 动态规划java

LeetCode 91&&639 动态规划java

小白写博客不会用画图,只能勉强用手写。。希望大家不要介意。。如果
有好的画图软件,希望大家告诉我一下!

1)91.解码方法

动态规划思路:
	对于字符串s上任意第i个字符,都可能可以**解码当前字符**或者与前**一个字符
	合并解码**,(如字符串"22",对于第2个“2”,解码当前字符相对于(2,2)=>BB,
	与前一个字符合并解码为(22)=>V)
	那么遍历这个字符串,对于i个字符,有以下情况:
	1)**字符为数字1~9**,说明可以解码当前字符;
		判断能否与前一个字符合并:
			1)如果第i-1个字符*10+ 当前字符 <=26,说明**当前字符可以与前一个
			字符合并解码**,此时该字符的解码数=前i-1个+前i-2个。
			2)如果不行,此时该字符的解码数=前i-1个。
	2)**字符为0**,说明当前字符不能解码(因为0没有对应的字母),只能与前一个
	字符合并解码,如果可以,那么第i个字符的解码数=前i-2个字符的解码数;
	如果不行,返回0。

代码:dp[i] 保存第i-1个字符的解码数

public int numDecodings(String s){
        if(s==null || s.length()==0)
            return 0;
        int len=s.length();
        int[] dp=new int[len+1];
        dp[0]=1;
        if(s.charAt(0)=='0')
            return 0;
        else
            dp[1]=1;
        //i is index of string
        //从1开始是为了防止下面s.charAt(i-1)报越界
        for(int i=1;i

图解:
LeetCode 91&&639 动态规划java_第1张图片

2)639 解码方法2 难度:困难

这道题相对于91多了一个字符 * ,字符 * 可以代表1~9的任意数字。方法不是很难,大致思路都是一样的,大家不用畏难,冲!!!

分析:

老套路,从头开始遍历字符串S,对于第i个字符:
1)**第i个字符为 *** ,先考虑单独解码
	1.1 单独解码:*** 表示 1~9 中任意一个数字**,对应 A-I 中的任意一个字母。前i个
		字符的解码可以表示在前i-1个字符的结尾加上 A-I 中任意一个字母,因此前i
		个字符的解码数=9*前i-1个字符的解码数,即**dp[i] +=dp[i-1]*9;**
	1.2 合并解码。合并解码有3种情况,前一个字符为1,2,*;
		1.2.1 **前一个字符为1**,那么他们可以表示 11~19 中任意一个数字,对应字母
		为 K-S ,即在前i-2个字符的结尾加上 K-S 任意一个字母,因此**dp[i] +=6 * dp[i-1]**
		1.2.2**前一个字符为2**,即2*,可以表示 21~26 上任意一个数字,对应U~Z中
		任意一个字母,因此,**dp[i] +=6 * dp[i-2]** 
		1.2.3 **前一个字符为***,那么 ** 可以表示 11~19 以及 21~26,对应字母就是
		A~I 以及 U~Z,此时相对于在前i-2个字符的结尾加上A~I或者U~Z,因此
		**dp[i] +=15 * dp[i-2]**
2) **第i个字符为数字**。首先考虑单个数字解码的情况。
	2.1 如果字符为 1~9,此时前i个字符的解码数=前i-1个字符的解码数
	2.2 如果字符为0,此时只能与前一个字符合并解码。前一个字符是1、2、*才可以
	解码,具体情况如下:
		2.2.1 前一个字符为1,此时对应 10~19 任意一个数字,前i个字符解码数=前i-2个字符解码数;
		2.2.2 前一个字符为2,有效数字为 20~26。只有当前字符小于7,前i个字符的解码数=前i-2个字符解码数;
		2.2.3 前一个字符为*,解码数取决于当前字符。如果当前字符小于7,那么 * 
		可以是1或者2,当前解码数=前i-2个解码数的两倍;如果当前字符大于7,那么 * 只能是
		1,此时解码数=前i-2个解码数;

代码:

public int  numDecodings(String s){
        if(s==null || s.length()==0)
            return 0;
        int len=s.length();
        int M=(int)Math.pow(10,9)+7;
        //dp[i] 表示第i-1个字符的解码数
        long[] dp=new long[len+1];
        dp[0]=1;
        if(s.charAt(0)=='0')
            return 0;
        else if(s.charAt(0)=='*')
            dp[1]=9;
        else
            dp[1]=1;
        //i is index of string
        for(int i=1;i6)//*只能为1
                        dp[i+1] = (dp[i+1] + dp[i-1]) % M;
                    else//*可以为1 也可以为2
                        dp[i+1] = ( dp[i+1] + dp[i-1]*2 ) % M;
                }
            }
        }
        return (int)dp[len];
    }

图解字符串s=“12**610”,dp初始化为{ 1,1,0,0,0,0,0,0,0 }
LeetCode 91&&639 动态规划java_第2张图片
LeetCode 91&&639 动态规划java_第3张图片

你可能感兴趣的:(算法,动态规划,java)