规定1和A对应,2和B对应,3和C对应...
那么一个数字字符串比如”111“就可以转化为:
“AAA","KA","AK"
给定一个只有数字字符组成的字符串str,返回有多少种转化结果。
分析:众所周知,算法面试的递归套路一共有四种,只有5%不在其中,这是一道典型的从左往右的递归题目。
求转换结果:
如果第一个位置是1,那么就有两种选择,要不要看第二个位置,如果不看,那么就到第二个位置决策,如果看,那么就到第三个位置决策
如果第一个位置是2,那么就有两种选择,要不要看第二个位置,如果不看,那么就到第二个位置决策,如果看,又有两种选择,如果第二个位置的数小于7,那么到第三个位置决策,如果大于6,那么到第二个位置决策
如果第一个位置大于2,那么直接到第二个位置决策
求数量:
base case: 如果i来到length表明已经找到了一条转换结果返回1,如果i位置的值是0字符,转换不了直接返回0表示0种结果
如果第一个位置是1,那么就有两种选择,要不要看第二个位置,如果不看,那么直接返回从第二个位置开始转换的所有结果,如果看,那么返回从第二个位置开始转换的所有结果+从第三个位置开始转换的所有结果
如果第一个位置是2,那么就有两种选择,要不要看第二个位置,如果不看,那么直接返回从第二个位置开始转换的所有结果,如果看,又有两种选择,如果第二个位置的数小于7,那么返回从第二个位置开始转换的所有结果+从第三个位置开始转换的所有结果,如果大于6,那么直接返回从第二个位置开始转换的所有结果
如果第一个位置大于2,那么直接返回从第二个位置开始转换的所有结果
代码:
public class Class1 {
public static void main(String[] args) {
String s = "1112123312121212121211222121";
char[] chars = s.toCharArray();
List<String> sequences = new ArrayList<String>();
System.out.println("sequences = " + sequences.size());
int process = process(chars, 0);
System.out.println("process = " + process);
}
/**
* 求所有转换结果
* @param chars 字符数组
* @param position 从第i个位置转换
* @param allResult 所有结果
* @param currentResult 当前结果
*/
private static void changeResult(char[] chars,int position,List<String> allResult,String currentResult){
HashMap<String,String> map = new HashMap<String, String>();
map.put("1","A");
map.put("2","B");
map.put("3","C");
map.put("4","D");
map.put("5","E");
map.put("6","F");
map.put("7","G");
map.put("8","H");
map.put("9","I");
map.put("10","J");
map.put("11","K");
map.put("12","L");
map.put("13","M");
map.put("14","N");
map.put("15","O");
map.put("16","P");
map.put("17","Q");
map.put("18","R");
map.put("19","S");
map.put("20","T");
map.put("21","U");
map.put("22","V");
map.put("23","W");
map.put("24","X");
map.put("25","Y");
map.put("26","Z");
if(position == chars.length){
allResult.add(currentResult);
return;
}
if(chars[position] == '1'){
//不看第二个位置
if(position+1 < chars.length){
currentResult += map.get(chars[position]+"");
changeResult(chars,position+1,allResult,currentResult);
}else{
currentResult += map.get(chars[position]+"");
allResult.add(currentResult);
return;
}
//看第二个位置
if(position+1 < chars.length && position+2 < chars.length){
currentResult += map.get(chars[position]+""+chars[position+1]);
changeResult(chars,position+2,allResult,currentResult);
}else if(position+1 < chars.length && position+2 >= chars.length){
currentResult += map.get(chars[position]+""+chars[position+1]);
allResult.add(currentResult);
return;
}else{
return;
}
}
if(chars[position] == '2'){
//不看第二个位置
if(position+1 < chars.length){
currentResult += map.get(chars[position]+"");
changeResult(chars,position+1,allResult,currentResult);
}else{
currentResult += map.get(chars[position]+"");
allResult.add(currentResult);
return;
}
//看第二个位置
if(chars[position+1] <= '6') {
if(position+1 < chars.length && position+2 < chars.length){
currentResult += map.get(chars[position]+""+chars[position+1]);
changeResult(chars,position+2,allResult,currentResult);
}else if(position+1 < chars.length && position+2 >= chars.length){
currentResult += map.get(chars[position]+""+chars[position+1]);
allResult.add(currentResult);
return;
}else{
return;
}
}else{
if(position+1 < chars.length){
currentResult += map.get(chars[position]+"");
changeResult(chars,position+1,allResult,currentResult);
}else{
currentResult += map.get(chars[position]+"");
allResult.add(currentResult);
return;
}
}
}
if(chars[position] > '2'){
//不看第二个位置
if(position+1 < chars.length){
currentResult += map.get(chars[position]+"");
changeResult(chars,position+1,allResult,currentResult);
}else{
currentResult += map.get(chars[position]+"");
allResult.add(currentResult);
return;
}
}
}
/**
* 求转换数量
* @param str 字符数组
* @param i 从第i个位置转换
* @return
*/
private static int process(char[] str,int i){
if(i == str.length){
return 1; //找到了一种转换结果
}
if(str[i] == '0'){
return 0; //'0'转换不了
}
if(str[i] == '1'){
int res = process(str,i+1); //不带下一个位置转换的所有结果
if(i+1 < str.length){
res += process(str,i+2);//带下一个位置转换的所有结果
}
return res;
}
if(str[i] == '2'){
int res = process(str,i+1); //不带下一个位置转换的所有结果
if(i+1 < str.length && str[i+1] <= '6'){
res += process(str,i+2);//带下一个位置转换的所有结果
}
return res;
}
return process(str,i+1); //如果是大于二,没得选择,不带下一个位置转换的所有结果
}
}