前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode第207题--Course Schedule

LeetCode第207题--Course Schedule

作者头像
felix
发布2018-06-12 16:08:53
7000
发布2018-06-12 16:08:53
举报
文章被收录于专栏:Felix的技术分享

LeetCode第207题–Course Schedule

原题

给出课程总数,用不同整数编号表示不同课程,用一个二维数组表示多组先修课程的顺序对。

比如:有2门课,要学课程1必须先学课程0,这是有效的。

代码语言:javascript
复制
2, [[1,0]]

如果有2门课,要学课程1必须先学课程0,要学课程0必须先学课程1,这是无效的。

代码语言:javascript
复制
2, [[1,0],[0,1]]

需要完成的就是这个方法:

代码语言:javascript
复制
    public boolean canFinish(int numCourses, int[][] prerequisites) {

    }   

测试数据:

代码语言:javascript
复制
8, [[1,0],[2,6],[1,7],[5,1],[6,4],[7,0],[0,5],[5,1],[6,4]]

解题思路

由课程的编号构成一幅有向图,方向为先修顺序,构造完成后只要判断图是否有环。

有向图数据结构

初始化时构造一张图,但只有顶点个事,顶点之间没有边相连。

用邻接表表示有向图。

调用addEdge()方法可以将课程之间先修关系写到图中。

代码语言:javascript
复制
    private class Digraph {

        private final int V;
        private ArrayList<Integer>[] adj;

        public Digraph(int V) {
            this.V = V;
            adj = (ArrayList<Integer>[]) new ArrayList[V];
            for (int v = 0; v < V; v++) {
                adj[v] = new ArrayList<Integer>();
            }
        }

        public void addEdge(int v, int w) {
            adj[v].add(w);
        }

        public int V() {
            return V;
        }

        public Iterable<Integer> adj(int v) {
            return adj[v];
        }

    }

判断有向图中是否有环

用一个数组boolean[] onStack保存递归调用期间栈上的所有顶点.

onStack[v]=true,记录顶点v出现在这次dfs中,在这次dfs结束后,是onStack[v]=false

在递归执行dfs的过程中,记录当前下当前顶点在递归调用栈中,这样以后的递归调用栈只要判断它的相连点是否在之前的递归调用栈中出现过,就能判断是否有环。

代码语言:javascript
复制
    private class DirectedCycle {
        private boolean[] marked;        // marked[v] 顶点v是否被访问过
        private boolean[] onStack;       //保存递归调用期间栈上的所有顶点。 onStack[v] = ?顶点v是否在栈中
        private boolean hasCycle;       // 有向图中是否环

        public DirectedCycle(Digraph G) {
            marked = new boolean[G.V()];
            onStack = new boolean[G.V()];
            hasCycle = false;
            for (int v = 0; v < G.V(); v++)   //对图中每一个没有被访问过的点做深度优先遍历
                if (!marked[v]) dfs(G, v);
        }


        /**
         * 从v顶点开始做深度优先遍历
         */
        private void dfs(Digraph G, int v) {
            onStack[v] = true;
            marked[v] = true;
            for (int w : G.adj(v)) {        //遍历所有顶点v的相连点
                if (hasCycle) return;       //如果已经找到一个环就不再dfs
                else if (!marked[w]) {      //对每一个未访问过的点继续dfs
                    dfs(G, w);
                } else if (onStack[w]) {    //顶点w在之前的递归调用栈中,并且已经被访问过,构成环
                    hasCycle = true;
                }
            }
            onStack[v] = false;             //顶点v所有的相连点遍历结束,顶点v退出当前调用栈
        }

        public boolean hasCycle() {
            return hasCycle;
        }
    }

主方法

代码语言:javascript
复制
     public boolean canFinish(int numCourses, int[][] prerequisites) {
        Digraph G = new Digraph(numCourses);
        for (int i = 0; i < prerequisites.length; i++) {
            for (int j = 0; j < prerequisites[i].length; j++) {
                G.addEdge(prerequisites[i][j], prerequisites[i][++j]);
            }
        }
        DirectedCycle dag = new DirectedCycle(G);

        return !dag.hasCycle();

    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年05月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LeetCode第207题–Course Schedule
    • 原题
      • 测试数据:
      • 解题思路
      • 有向图数据结构
      • 判断有向图中是否有环
      • 主方法
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档