- 题目:规定1和A对应、2和B对应、3和C对应…
那么一个数字字符串比如"111”就可以转化为:
“AAA”、“KA"和"AK”
给定一个只有数字字符组成的字符串str,返回有多少种转化结果 - 接收信息:index
- 判断: // 可能性一:i位置的数字转为字母 (因为已经排除0,和i到末尾。所以一定成立)
- // 可能性二:i和i+1的位置组成一个【1~26】内的数字,转换成字母
- basecase:当index位置为0时直接说明当前组合无效。不越界时把两位字符转成数字,只有<=26的才有效
代码 - 传出信息:i+=1 或 i+=2
public static int number(String str) {
if (str == null || str.length() == 0) {
return 0;
}
return process1(str.toCharArray(), 0);
}
public static int process(char[] str, int i) {
if (i == str.length) {
return 1;
}
if (str[i] == '0') {
return 0;
}
int ways = process(str, i + 1);
if (i + 1 < str.length && (str[i] - '0') * 10 + str[i + 1] - '0' < 27) {
ways += process(str, i + 2);
}
return ways;
}
public static int dp1(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
int[] dp = new int[N + 1];
dp[N] = 1;
for (int i = N - 1; i >= 0; i--) {
if (str[i] != '0') {
int ways = dp[i + 1];
if (i + 1 < str.length && (str[i] - '0') * 10 + str[i + 1] - '0' < 27) {
ways += dp[i + 2];
}
dp[i] = ways;
}
}
return dp[0];
}
public static int dp2(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int N = str.length;
if (str[0] == '0') {
return 0;
}
int[] dp = new int[N];
dp[0] = 1;
for (int i = 1; i < N; i++) {
if (str[i] == '0') {
if (str[i - 1] == '0' || str[i - 1] > '2' || (i - 2 >= 0 && dp[i - 2] == 0)) {
return 0;
} else {
dp[i] = i - 2 >= 0 ? dp[i - 2] : 1;
}
} else {
dp[i] = dp[i - 1];
if (str[i - 1] != '0' && (str[i - 1] - '0') * 10 + str[i] - '0' <= 26) {
dp[i] += i - 2 >= 0 ? dp[i - 2] : 1;
}
}
}
return dp[N - 1];
}