前言:
作为一个外乡人进入南通,我成功被社区工作人员隔离在家,并贴心的送来了体温计以及封条,给我隔离的严严实实,同时还要汇报自己的体温给社区阿姨,在这种情况下我只能开始写点东西来打发时间(虽然一整天都在看专业视频)!
这两天一直在投递简历,结果都是惨不忍睹,项目经验太差,没什么出彩的地方,所以我成了一条咸鱼,但是也不能放弃自己不是,还是要拿起书本,打开电脑,敲上一段System.out.println("Hello World")
前两天一个HR发来一份笔试题目,告诉我若能通过则可以进行下一轮面试,于是一轮紧张又刺激的笔试开始了,看着题目半天写出来一堆A、B、C…深刻体会到了什么叫做从开始到放弃。作为一个打不死的小强怎么能够放弃,毕竟我夸下海口给HR说四十分钟,但是此时二十分钟已经过去了,还么想到如何解决(手动狗头),这时候一定要感谢HR,说晚上八点之前给她就行,好了又一轮紧张又刺激的笔试开始了。
题目如下:
有兴趣的朋友可以做一下。
自己一开始没想到回溯算法,自己的想法虽然是回溯的思想,但是没有想到该如何实现,于是群里开始了一轮请教:
于是呢在一位大佬的点拨下说到了回溯算法,想起来大学《数据结构》的时候学过这个算法,但是我忘记了啊(一万只草泥马飞奔),然后百度用起来:
当然了看这些是看不懂了,想要懂还是根据问题看思想,这其中提到的八皇后的问题,就是在4x4棋盘上,使得4个皇后不能在同行同列以及同斜线上。
针对这个问题,当我们放置第一个皇后,那边第二个皇后的放置有四种选择,
当放置第二个皇后时,发现第三个皇后很难放置,于是需要对第二个皇后更改位置,重新放置。
于是就有下列情况
当放置第三个皇后时,第四个皇后又无法放置,因此就需要重新放置第三个皇后,但是第三个皇后已经没有第二种选择,于是继续向上处理,重新放置第二个皇后,发现也没有第二个选择,依次向上查看更改第一个皇后的位置,如下:
(图片来自https://www.jianshu.com/p/dd3c3f3e84c0)
以这种思想,走不通的路就返回寻找其它的路。
于是我这个问题也就解决了,我这个问题中需要对遍历的结果进行判断,判定结果中的数据是否达到了满足条件(条件为是否达到了预期的长度!),因此通过这种思想,如果满足条件则将结果加入输出数据中,若不满足,则继续执行。
于是代码也就能出来了!高能
package com.unit;
import java.util.*;
import static com.unit.WordUnit.getWords;
/**
* @author chenmo
*/
public class BackTrackingUnit {
private List<Integer> lists = new ArrayList<Integer>();
/**
* 初始化输出字符串
*/
private StringBuilder result = new StringBuilder();
/**
* 初始化第三方字符串,存储相应的值
*/
private StringBuilder stringBuilder = new StringBuilder();
/**
* 输入数组输出相应的值
* @param arr
* @return
*/
public StringBuilder getLetterString(Integer[] arr) {
if(arr.length == 0) {
return result;
}
List< Integer> list = new ArrayList<Integer>(Arrays.asList(arr));
for (int i = 0; i < list.size(); i++) {
//判断数组的值是否大于9,若大于9则拆分数值
if (list.get(i)>9){
int num = list.get(i);
list.set(i,num/10);
list.add(i+1,num%10);
}
}
this.lists = list;
//执行回溯,从长度为0开始遍历
reCall(0);
return result;
}
/**
* 回溯算法
* @param strLength 字符串当前长度
*/
private void reCall(int strLength) {
//判断是否遍历成功,即当前长度是否等于最终长度,若成功则将组成的字母添加到结果集中
if(strLength == lists.size()) {
result.append(stringBuilder.toString());
result.append(" ");
return;
}
char[] arrays = getWords(lists.get(strLength)).toCharArray();
for(char ch: arrays) {
stringBuilder.append(ch);
reCall(strLength + 1);
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
}
}
}
package com.unit;
import java.util.HashMap;
import java.util.Map;
/**
* @author chenmo
*/
public class WordUnit {
/**
* 根据数字对应相应字母
* @param i
* @return
*/
public static String getWords(Integer i) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(0, "");
map.put(1, "");
map.put(2, "abc");
map.put(3, "def");
map.put(4, "ghi");
map.put(5, "jkl");
map.put(6, "mno");
map.put(7, "pqrs");
map.put(8, "tuv");
map.put(9, "wxyz");
return map.get(i);
}
}
package com.test;
import com.unit.BackTrackingUnit;
/**
* 测试
* @author chenmo
*/
public class BackTrackingTest {
public static void main(String[] args) {
BackTrackingUnit backTrackingUnit = new BackTrackingUnit();
// System.out.println("请输入几个数并用逗号隔开:");
// Scanner scanner = new Scanner(System.in);
// String string = scanner.next();
// String[] StringArr = string.split(",");
// Integer[] arr = (Integer[]) ConvertUtils.convert(StringArr,Integer.class);
Integer[] arr = new Integer[]{9,3};
StringBuilder res = backTrackingUnit.getLetterString(arr);
System.out.println(res);
}
}
当然了这个题目还有第二个问题,就是能够处理0-99的数字,于是我这里对大于9的数字做了处理,于是输入0-99的数字都可以输出相应的结果。
题解想法我已经做了注释,可以根据注释来理解我的这个想法。欢迎指正,共同学习。