博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode----207. Course Schedule
阅读量:4113 次
发布时间:2019-05-25

本文共 2603 字,大约阅读时间需要 8 分钟。

链接:

大意:

给定一个整数num为所需学习的课程数目,一个二维整数数组pre为修习课程的先决条件。若pre中某个一维数组为[0,1],则表示要学习0号课程,则必须先学习1号课程。规定:课程编号为0~num-1。现在要求判断是否有一种安排使得可以修习完所有课程。例子:

思路:

说的这么多,其实就是在一个有向图中判断是否存在拓扑序列。

通过num值,构造一个每个节点的入度数组degree,以及构造一个以每个节点为边的起点的边信息graph(其实就是构图)。

通过pre数组,对degree和graph进行初始化。

接下来就是模拟寻找拓扑序列了。

首先,找到图中剩余顶点中的一个入度为0的顶点,之后将以该顶点为起点的边所指向的节点的入度减1,同时需要将该节点置为已访问(不然下次找入度为0的顶点时又会找到它)。之后便是重复该过程。知道找到的顶点数(课程数)等于num(返回true)或者找不到入度为0的点了 (返回false)

代码:

class Solution {    // 判断一个图是否可以找出一个拓扑序列    public boolean canFinish(int num, int[][] pre) {        int[] degree = new int[num]; // 记录每个节点的入度        List
[] graph = new ArrayList[num]; // 记录各个边的关系 for (int i = 0; i < num; i++) { graph[i] = new ArrayList<>(); } for (int[] nums : pre) { degree[nums[0]]++; graph[nums[1]].add(nums[0]); // nums[1] -> nums[0] } int count = 0; boolean[] visited = new boolean[num]; // 记录节点是否已被访问 while (count < num) { int curIdx = -1; // 尝试找到一个入度为0的点 for (int i = 0; i < degree.length; i++) { if (!visited[i] && degree[i] == 0) { curIdx = i; break; } } // 没找到入度为0的点 if (curIdx == -1) break; visited[curIdx] = true; for (int tail : graph[curIdx]) { degree[tail]--; } count++; } return count == num; }}

结果:

结论:

效率有点低,需要改进。

改进:

猜测主要性能瓶颈是在while循环中尝试找到入度为0的点的for循环中,需要遍历一次degree数组。可以使用一个列表idxs首先存储一开始入度为0的点,然后依次取出list的点,判断该点指向的那些点入度减1后是否为0.若为0,则将指向的该点也加入idxs

当idxs为空时跳出循环,并判断count是否与num相等

class Solution {    // 判断一个图是否可以找出一个拓扑序列    public boolean canFinish(int num, int[][] pre) {        int[] degree = new int[num]; // 记录每个节点的入度        List
[] graph = new ArrayList[num]; // 记录各个边的关系 for (int i = 0; i < num; i++) { graph[i] = new ArrayList<>(); } for (int[] nums : pre) { degree[nums[0]]++; graph[nums[1]].add(nums[0]); // nums[1] -> nums[0] } int count = 0; ArrayList
idxs = new ArrayList<>(); // 存储所有当前入度为0的点的位置 // 记录入度为0的点 for (int i = 0; i < degree.length; i++) { if (degree[i] == 0) idxs.add(i); } while (!idxs.isEmpty()) { int curIdx = idxs.remove(idxs.size() - 1); for (int tail : graph[curIdx]) { if (--degree[tail] == 0) // 又找到一个新的入度为0的点 idxs.add(tail); } count++; } return count == num; }}

 

 

 

转载地址:http://baesi.baihongyu.com/

你可能感兴趣的文章
k8s web终端连接工具
查看>>
手绘VS码绘(一):静态图绘制(码绘使用P5.js)
查看>>
手绘VS码绘(二):动态图绘制(码绘使用Processing)
查看>>
基于P5.js的“绘画系统”
查看>>
《达芬奇的人生密码》观后感
查看>>
论文翻译:《一个包容性设计的具体例子:聋人导向可访问性》
查看>>
基于“分形”编写的交互应用
查看>>
《融入动画技术的交互应用》主题博文推荐
查看>>
链睿和家乐福合作推出下一代零售业隐私保护技术
查看>>
Unifrax宣布新建SiFAB™生产线
查看>>
艾默生纪念谷轮™在空调和制冷领域的百年创新成就
查看>>
NEXO代币持有者获得20,428,359.89美元股息
查看>>
Piper Sandler为EverArc收购Perimeter Solutions提供咨询服务
查看>>
RMRK筹集600万美元,用于在Polkadot上建立先进的NFT系统标准
查看>>
JavaSE_day12 集合
查看>>
JavaSE_day14 集合中的Map集合_键值映射关系
查看>>
Day_15JavaSE 异常
查看>>
异常 Java学习Day_15
查看>>
JavaSE_day_03 方法
查看>>
day-03JavaSE_循环
查看>>