615

来源:互联网 发布:同声传译软件 编辑:程序博客网 时间:2024/06/06 03:40

2017.9.11

刚开始想的是,建立parent 和 children的树,如果有既是children 又是parent的节点,那么就返回false。

这种方法没有超时,但是超出了空间限制。


后来学习到采用拓扑排序的办法。关于图的思路写在了代码的注释里边。

在细节的处理方面有不同的方法。一个是最后的最后统一判断是不是还有入度不为0的点。这样会超时。

后来是在找入度为0的点的时候就进行判断,然而还是会超时。

后来又优化了许多地方。但是总是超时,我也没办法,实在是不知道为啥了。就先这样吧。


再再后来,我知道了,是找到一个入度为0得点之后,这个点的入度应该改变为-1,不然会重复选取。

终于找到了自己错误的地方,好开心。


最初的超时代码

public static class myCourse{HashSet<Integer> parent;HashSet<Integer> children;public myCourse(){parent = new HashSet<Integer>();children = new HashSet<Integer>();}}public static boolean canFinish1(int numCourses, int[][] prerequisites) {        // Write your code heremyCourse []arr = new myCourse[numCourses];for(int []x : prerequisites){if(arr[x[0]] == null){arr[x[0]] = new myCourse();}if(!arr[x[0]].children.contains(arr[x[1]])){arr[x[0]].children.add(x[1]);}if(arr[x[1]] == null){arr[x[1]] = new myCourse();}if(!arr[x[1]].parent.contains(arr[x[0]])){arr[x[1]].parent.add(x[0]);}for(int tmp : arr[x[1]].children){if(tmp == x[0]){return false;}if(!arr[x[0]].children.contains(tmp)){arr[x[0]].children.add(tmp);}}for(int tmp : arr[x[0]].parent){if(tmp == x[1]){return false;}if(!arr[x[1]].parent.contains(tmp)){arr[x[1]].parent.add(tmp);}}}return true;    }

后来的超时代码,就是最后统一检查入度的方法。

public static boolean canFinish2(int numCourses, int[][] prerequisites){// 首先是要构建图。ArrayList<HashSet<Integer>> list = new ArrayList<HashSet<Integer>>();// 先建立头结点。for(int i = 0; i < numCourses; i++){list.add(new HashSet<Integer>());}//建立所有的后序链表。     // inDegree计算所有的节点的入度。int []inDegree = new int[numCourses];for(int []x : prerequisites){if(!list.get(x[0]).contains(x[1])){list.get(x[0]).add(x[1]);inDegree[x[1]] ++;}}//找到一个入度为0的节点,开始遍历。for(int j = 0; j < numCourses; j++){    int i = 0;for(i = 0; i < inDegree.length;i++){//在这里找到了一个入度为0的点。if(inDegree[i] == 0 && !list.get(i).isEmpty()){Iterator ite = list.get(i).iterator();while(ite.hasNext()){int tmp = (int)ite.next();inDegree[tmp]--;ite.remove();}break;}}}for(int i = 0; i< inDegree.length;i++){if(inDegree[i] != 0){return false;}}return true;}

最后最后,把能简化的都简化了,然而还是超时的代码。

后来稍稍修改一下。就AC了。

public static boolean canFinish(int numCourses, int[][] prerequisites){// 首先是要构建图。ArrayList<HashSet<Integer>> list = new ArrayList<HashSet<Integer>>();// 先建立头结点。for(int i = 0; i < numCourses; i++){list.add(new HashSet<Integer>());}//建立所有的后序链表。 for(int []x : prerequisites){list.get(x[0]).add(x[1]);}    // inDegree计算所有的节点的入度。int []inDegree = new int[numCourses];for(HashSet set : list){Iterator ite = set.iterator();while(ite.hasNext()){inDegree[(int)ite.next()]++;}}//找到一个入度为0的节点,开始遍历。for(int j = 0; j < numCourses; j++){int i = 0;for(i = 0; i< numCourses;i++){//在这里找到了一个入度为0的点。if(inDegree[i] == 0){break;}}if(i == numCourses){return false;}                        //这里这里就是在这里啊,这个我忽视了啊啊啊啊。
                        inDegree[i] = -1;
  Iterator ite = list.get(i).iterator();while(ite.hasNext()){inDegree[(int)ite.next()]--;}}return true;}



原创粉丝点击