done 苹果一个后端组的oa
题目:
/** * The Problem: * * We have a list of tasks. Each task can depend on other tasks. * For example if task A depends on task B then B should run before A. * * Implement the "getTaskWithDependencies" method such that it returns a list of task names in the correct order. * * For example if I want to execute task "application A", the method should return a list with "storage,mongo,application A". * * List of Tasks: * * - name: application A * dependsOn: * - mongo * * - name: storage * * - name: mongo * dependsOn: * - storage * * - name: memcache * * - name: application B * dependsOn: * - memcache * * The Java program is expected to be executed succesfully. */
一开始的做法:
import java.io.*; import java.util.*; import org.junit.*; import org.junit.runner.*; public class Solution { private static List<String> getTaskWithDependencies(List<Task> tasks, String dependsOn) { // TODO: please implement logic here //定义 int numCourses = tasks.size(); boolean[] visited = new boolean[numCourses]; Stack<String> stack = new Stack<>(); //判断 //v是课程的数量 0-4 for (int i = 0; i < numCourses; i++) { //有环就是空 if (!topologicalSort(tasks, i, tasks.get(i).getName(), stack, visited, new boolean[numCourses])) return new ArrayList<>(); } //定义结果 //int[] result = new int[numCourses]; List<String> result = new ArrayList<>(); //往里面加 while (!stack.isEmpty()) { result.add(stack.pop()); } return result; } private static boolean topologicalSort(List<Task> adj, int taskIndex, String taskName, Stack<String> stack, boolean[] visited, boolean[] isLoop) { //提前判断一下 if (visited[taskIndex]) return true; if (isLoop[taskIndex]) return false; //设定v是有循环的,因为v是大的[],就分析这么一次。类比,task是大的,就分析一次。所以signature要改。 isLoop[taskIndex] = true; //u需要具体问题具体分析。有回路就是false。类比,name需要具体问题具体分析。 //所以怎么迁移到这道题呢?adj.get(v)是Task。那都换成Task不就行了? //两个不一样类型。。。注释掉会不会有影响?会,主要是中途false了就不能加了。一直是true才能加 //别用for each循环不就行了 if (!adj.get(taskIndex).getDependsOn().isEmpty()) { if (!topologicalSort(adj, taskIndex, adj.get(taskIndex).getDependsOn().toString(), stack, visited, isLoop)) {System.out.println("false here"); return false;} } else { if (!topologicalSort(adj, taskIndex, "", stack, visited, isLoop)) {System.out.println("false here1"); return false;} } //访问完v了 visited[taskIndex] = true; //把课程加到stack里,后续要拿来排序。所以应该是string对吧。处理下就行了。 System.out.println("adj.get(taskIndex).getName() = " + adj.get(taskIndex).getName()); stack.push(adj.get(taskIndex).getName()); return true; } public static void main(String[] args) { JUnitCore.main("Solution"); } @Test public void testGetTaskDependenciesForApplicationA() { Assert.assertEquals( Arrays.asList( "storage", "mongo", "application A" ), getTaskWithDependencies(TaskList.getTasks(), "application A") ); } } /** * Definition of a Task */ class Task { private final String name; private final List<String> dependsOn; Task(String name) { this(name, new ArrayList<>()); } Task(String name, List<String> dependsOn) { this.name = name; this.dependsOn = dependsOn; } public String getName() { return this.name; } public List<String> getDependsOn() { return this.dependsOn; } } class TaskList { public static List<Task> getTasks() { List<Task> tasks = new ArrayList<>(); tasks.add(new Task("application A", Arrays.asList("mongo"))); tasks.add(new Task("storage")); tasks.add(new Task("mongo", Arrays.asList("storage"))); tasks.add(new Task("memcache")); tasks.add(new Task("application B", Arrays.asList("memcache"))); return tasks; } }
后来觉得不可行,把自定义的类放到递归中去,根本就无法debug。还是一开始就把自定义的类变成数字编号吧。问题是会出现两条路。
/** * The Problem: * * We have a list of tasks. Each task can depend on other tasks. * For example if task A depends on task B then B should run before A. * * Implement the "getTaskWithDependencies" method such that it returns a list of task names in the correct order. * * For example if I want to execute task "application A", the method should return a list with "storage,mongo,application A". * * List of Tasks: * * - name: application A * dependsOn: * - mongo * * - name: storage * * - name: mongo * dependsOn: * - storage * * - name: memcache * * - name: application B * dependsOn: * - memcache * * The Java program is expected to be executed succesfully. */ import java.io.*; import java.util.*; import org.junit.*; import org.junit.runner.*; public class Solution { private static List<String> getTaskWithDependencies(List<Task> tasks, String dependsOn) { // TODO: please implement logic here //定义输入数据。 int numTasks = 5; //如果需要转换,可以用hashmap对应string和编号 int prerequisites[][]={{0,1},{1,2},{4,3}}; //调用排序,获得result数组 int[] result = findOrder(numTasks, prerequisites); for (int i = 0; i < result.length; i++) { System.out.println("result[i] = " + result[i]); } //如果需要转换,可以用hashmap对应string和编号 ArrayList<String> res = new ArrayList<>(); res.add("storage"); res.add("mongo"); res.add("application A"); return res; } public static int[] findOrder(int numTasks, int[][] prerequisites) { List<List<Integer>> adj = new ArrayList<>(numTasks); for (int i = 0; i < numTasks; i++) adj.add(i, new ArrayList<>()); for (int i = 0; i < prerequisites.length; i++) adj.get(prerequisites[i][1]).add(prerequisites[i][0]); boolean[] visited = new boolean[numTasks]; Stack<Integer> stack = new Stack<>(); for (int i = 0; i < numTasks; i++) { if (!topologicalSort(adj, i, stack, visited, new boolean[numTasks])) return new int[0]; } int i = 0; int[] result = new int[numTasks]; while (!stack.isEmpty()) { result[i++] = stack.pop(); } return result; } private static boolean topologicalSort(List<List<Integer>> adj, int v, Stack<Integer> stack, boolean[] visited, boolean[] isLoop) { if (visited[v]) return true; if (isLoop[v]) return false; isLoop[v] = true; for (Integer u : adj.get(v)) { if (!topologicalSort(adj, u, stack, visited, isLoop)) return false; } visited[v] = true; stack.push(v); return true; } public static void main(String[] args) { JUnitCore.main("Solution"); } @Test public void testGetTaskDependenciesForApplicationA() { Assert.assertEquals( Arrays.asList( "storage", "mongo", "application A" ), getTaskWithDependencies(TaskList.getTasks(), "application A") ); } } /** * Definition of a Task */ class Task { private final String name; private final List<String> dependsOn; Task(String name) { this(name, new ArrayList<>()); } Task(String name, List<String> dependsOn) { this.name = name; this.dependsOn = dependsOn; } public String getName() { return this.name; } public List<String> getDependsOn() { return this.dependsOn; } } class TaskList { public static List<Task> getTasks() { List<Task> tasks = new ArrayList<>(); tasks.add(new Task("application A", Arrays.asList("mongo"))); tasks.add(new Task("storage")); tasks.add(new Task("mongo", Arrays.asList("storage"))); tasks.add(new Task("memcache")); tasks.add(new Task("application B", Arrays.asList("memcache"))); return tasks; } }
后来去stackoverflow上问了,获得这个答案(感谢德国的编辑,孟加拉国的好兄弟!世界码农一家亲!)
其实用递归就行了,递归来来去去就是一条路,根本不会出现两条路的情况。递归学得不到位啊!
/** * The Problem: * * We have a list of tasks. Each task can depend on other tasks. * For example if task A depends on task B then B should run before A. * * Implement the "getTaskWithDependencies" method such that it returns a list of task names in the correct order. * * For example if I want to execute task "application A", the method should return a list with "storage,mongo,application A". * * List of Tasks: * * - name: application A * dependsOn: * - mongo * * - name: storage * * - name: mongo * dependsOn: * - storage * * - name: memcache * * - name: application B * dependsOn: * - memcache * * The Java program is expected to be executed succesfully. */ import java.io.*; import java.util.*; import org.junit.*; import org.junit.runner.*; public class Solution { private static List<String> getTaskWithDependencies(List<Task> tasks, String dependsOn) { //初始化一个resultString StringBuilder resultString = new StringBuilder(); for (int i = 0; i < tasks.size(); i++) { System.out.println(tasks.get(i).getName()); } //筛选出必须有name = dependsOn的每个人物自己 Task task = tasks.stream().filter(x -> dependsOn.equalsIgnoreCase(x.getName())) .findAny().get(); //如果非空 if (task.getDependsOn() != null && !task.getDependsOn().isEmpty()) { for (String newDependsOn : task.getDependsOn()) { //递归一下,递归栈越深的放前面。storage先append了,然后mongo List<String> res = getTaskWithDependencies(tasks, newDependsOn); //用逗号分隔结果 for (String ele : res) { resultString.append(ele).append(","); System.out.println(""); System.out.println("resultString = " + resultString); System.out.println(""); } } } //最后加上application A本身 resultString.append(dependsOn); System.out.println("resultString after append = " + resultString); return Arrays.asList(resultString.toString().split(",")); } public static void main(String[] args) { JUnitCore.main("Solution"); } @Test public void testGetTaskDependenciesForApplicationA() { Assert.assertEquals( Arrays.asList( "storage", "mongo", "application A" ), getTaskWithDependencies(TaskList.getTasks(), "application A") ); } } /** * Definition of a Task */ class Task { private final String name; private final List<String> dependsOn; Task(String name) { this(name, new ArrayList<>()); } Task(String name, List<String> dependsOn) { this.name = name; this.dependsOn = dependsOn; } public String getName() { return this.name; } public List<String> getDependsOn() { return this.dependsOn; } } class TaskList { public static List<Task> getTasks() { List<Task> tasks = new ArrayList<>(); tasks.add(new Task("application A", Arrays.asList("mongo"))); tasks.add(new Task("storage")); tasks.add(new Task("mongo", Arrays.asList("storage"))); tasks.add(new Task("memcache")); tasks.add(new Task("application B", Arrays.asList("memcache"))); return tasks; } }
打印的log:
JUnit version 4.13.2 .application A storage mongo memcache application B application A storage mongo memcache application B application A storage mongo memcache application B resultString after append = storage resultString = storage, resultString after append = storage,mongo resultString = storage, resultString = storage,mongo, resultString after append = storage,mongo,application A Time: 0.015 OK (1 test)
使用Stream的filter进行过滤,eg只保留男性。
Stream<Person> personStream = collection.stream().filter( person -> "男".equals(person.getGender())//只保留男性 );
教程:https://blog.csdn.net/qq_33829547/article/details/80279488