9-8日 携程 开发岗第二题 代码详解
九月八日的携程JAVA开发岗,真的太难了
当是只做出了AC 88%第一题,现在补充 第二题的代码。有错误的地方希望大家纠正,先看下题目
思想讲解:
这个题目其实主要考的是笛卡尔积,先使用笛卡尔积的算法,把所有的可能都得到,再去判断是否出现重复流程
有错误的地方请指正
别觉得代码多 ,重点代码只在 fun(), main方法里只是做了 输入 输出 ,判断是否为重复流
import java.util.*;
public class demo2 {
static StringBuilder res = new StringBuilder();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
String str = scanner.nextLine(); //输入
String strs[] = str.split(" "); //根据空格截取每一段
List<List<String>> lists = new ArrayList<>();
for (int i = 0; i < strs.length; i++) {
lists.add(Arrays.asList(strs[i].split("")));
}
Stack<String> stack = new Stack<>();
List<List<String>> result = new ArrayList<>();
fun(lists,0,stack,result);
// 假设数据为 [[a,b,c],[d,c,f]] ,那么sets[0] 所存储的就是 a,b,c, sets[1] 所存储的就是 a,b,c,d,f
// 作用是为了判断流程中是否包含重复流程
// 采用这种结构是为了降低复杂度,如果在两层循环中再嵌套一个 for循环去判断是否有重复流,那时间复杂度一下子就上去了。但是借助了set之后,就可以把第三层循环干掉
ArrayList<HashSet<String>> sets = new ArrayList<>();
HashSet<String> set = new HashSet<>();
for (int i = 0; i < lists.size(); i++) {
for (int j = 0; j < lists.get(i).size(); j++) {
set.add(lists.get(i).get(j));
}
sets.add(new HashSet<>(set));
}
Boolean flag = false; //判断是否出现重复
for (int i = 0; i < result.size(); i++) {
flag = false;
for (int j = 0; j < result.get(i).size(); j++) {
String s= result.get(i).get(j);
if(j!=0&&sets.get(j-1).contains(s)){ //判断是否出现重复
flag = true;
}
System.out.print(s);
}
if (flag){
System.out.print("--重复流程");
}
System.out.println();
}
}
}
/**
*
* @param originLists 原始的一个二维数组
* @param index 遍历二维数组的一位数组的位置 [[a,b,c],[d,e,f]] index == 0 表示 [a,b,c]
* @param stack 用于存储每次得到的结果 ,[a,d] 就是其中一个,
* 先将a入栈,d再入栈,然后d出栈,e入栈,e出栈,f入栈,f出栈,
* 此时,def都遍历完了,那么此时就应该是a出栈,b入栈 ,重复上面的操作
* @param result 存储得到的结果集
* @param <T> 泛型
*/
public static <T> void fun(List<List<T>> originLists,int index,Stack<T> stack,List<List<T>> result){
List<T> list = originLists.get(index); //获得原始数组中的其中一个数组元素
for (int i = 0; i < list.size(); i++) { //遍历list中的每个元素
stack.push(list.get(i)); //遍历得到的元素压入栈中
if(index == originLists.size()-1){//表明已经到达了原始数组的最后一个元素,也表明了,当前stack为其中一个子集
List<T> res = new ArrayList<>(stack); //生成新的数组,存入结果集中
result.add(res); //将结果存入result集合中
stack.pop(); //出栈栈顶元素
continue;
}
fun(originLists,index+1,stack,result); //递归调用
stack.pop(); //出栈栈顶元素
}
}
}
查看12道真题和解析