LeetCode207 Course Schedule

LeetCode207 Course Schedule

问题描述

here are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

问题分析

这道题的提示也说到了,这道题就是判断有向图是否存在环路。那么还是图的那一套,广度优先和深度优先。在这里我选择了深度优先,为了提高算法的效率要要确定哪些是已经遍历过的节点,从而及时的剪枝。

代码如下

Java代码


public boolean canFinish(int numCourses, int[][] prerequisites) {
     //初始化List
    List<List<Integer>> list = new ArrayList<>(numCourses);
     for (int i = 0; i <numCourses ; i++) {
         list.add(new ArrayList<>());
     }
     //给每个节点添加子节点
    for (int[] array: prerequisites
          ) {
         list.get(array[0]).add(array[1]);
     }
     //初始化全局已访问节点数组
     boolean[] visitedPre = new boolean[numCourses];
     for (int i = 0; i < numCourses; i++) {
         //当全局未访问,对该节点的路径进行递归,如果错误,返回false,否则继续
         if(!visitedPre[i]&&!help(i,list,new boolean[numCourses],visitedPre)) return false;
     }
     //全部路径搜寻完毕,没有环状路径
     return true;

 }
 boolean help(int from,List<List<Integer>> lists,boolean[] visited,boolean[] visitedPre){
     //如果当前节点全局未访问
     if(!visitedPre[from]){
         //当前节点设为该路径的未访问
         visited[from]=true;
         //遍历子节点
         for (int nextFrom: lists.get(from)){
             //如果该该节点出现在该路径重复出现,说明出环,返回false
             if(visited[nextFrom]||!visitedPre[from]&&!help(nextFrom,lists,visited,visitedPre))
                 return  false;
         }
         //将路径数组恢复
         visited[from] = false;
         //将该节点设为全局已访问
         visitedPre[from]=true;

     }
     return true;

 }

LeetCode学习笔记持续更新
GitHub地址 https://github.com/yanqinghe/leetcode
CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值