题目描述
规定1和A对应、2和B对应、3和C对应…26和Z对应 那么一个数字字符串比如"111”就可以转化为: “AAA”、“KA"和"AK”
解题方案
暴力递归
解题思路:
把字符串转成字节数组.
我们去考察每一个位置上如何转化.
里面有几个情况,
第一遇到0时,如果单独遇到0 ,说明当前这个方案无效直接返回0.
第二.当两个字符组成一个字母时,如果大于27 也认为无效.
考察好这两种情况,就可以撸代码了
代码演示
/**
* 暴力递归
* @param str
* @return
*/
public static int way(String str){
if (null == str || str.length() == 0){
return 0;
}
char[] chars = str.toCharArray();
return process(chars,0);
}
/**
* 递归
* @param chs
* @param i
* @return
*/
public static int process(char[]chs,int i){
//base case 越界说明已经考察完了 返回1
if(i == chs.length){
return 1;
}
//单独遇到0 说明当前的策略有问题,直接返回0
if(chs[i] == '0'){
return 0;
}
//当前一位数字组成字母的情况
int ways = process(chs,i + 1);
//两位字符组成的情况 判断越界和不能超过 26
if(i + 1 < chs.length && (chs[i] - '0') * 10 + chs[i + 1] - '0' < 27){
//两种情况累加
ways += process(chs,i + 2);
}
return ways;
}
动态规划
动态规划就是把递归过程转换成从表种取数据的过程,
就是递归的改写.,
改写的步骤,
1.先观察base case 如果从N 结束,那么递归表就从N -1 开始赋值
2.递归求值的过程就是把递归过程改成从表种拿
3.返回值 就是递归最开始的调用时状态.
代码演示
/**
* 动态规划
* @param str
* @return
*/
public static int dp(String str){
if (str == null || str.length() == 0){
return 0;
}
char[] chars = str.toCharArray();
int N = chars.length;
int[]dp = new int[N + 1];
// 递归时 越界返回1 base case 转成初始化.这里也初始化为1
dp[N] = 1;
//开始赋值 把递归里的两种情况在dp表里拿
for(int i = N - 1;i >= 0;i--){
int p1 = dp[i + 1];
if(i + 1 < chars.length && (chars[i] - '0') * 10 + chars[i + 1] - '0' < 27){
p1 += dp[i + 2];
}
dp[i] = p1;
}
//返回值 就是递归最早的调用状态.
return dp[0];
}