LeetCode-207. 课程表【深度优先搜索 广度优先搜索 图 拓扑排序】

LeetCode-207. 课程表【深度优先搜索 广度优先搜索 图 拓扑排序】

  • 题目描述:
  • 解题思路一:拓扑排序,检查图是否有环。有环代表不能完成,返回False。
  • 解题思路二:深度优先遍历
  • 解题思路三:广度优先搜索(就是拓扑排序)

题目描述:

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

示例 2:

输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

提示:

1 <= numCourses <= 2000
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有课程对 互不相同

解题思路一:拓扑排序,检查图是否有环。有环代表不能完成,返回False。

需要注意的点是

  1. 构建入度表和邻接表
  2. 队列实现
class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:indeg = [0] * numCourses # 入度表e = [[] for _ in range(numCourses)] # 邻接表for prerequisite in prerequisites:u, v = prerequisite[1], prerequisite[0]indeg[v] += 1e[u].append(v)queue = deque()for i in range(numCourses):if indeg[i] == 0:queue.append(i)ans = 0while queue:cur = queue.popleft()ans += 1for v in e[cur]:indeg[v] -= 1if indeg[v] == 0:queue.append(v)return numCourses == ans# 另一种写法
from collections import dequeclass Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:indegrees = [0 for _ in range(numCourses)]adjacency = [[] for _ in range(numCourses)]queue = deque()# Get the indegree and adjacency of every course.for cur, pre in prerequisites:indegrees[cur] += 1adjacency[pre].append(cur)# Get all the courses with the indegree of 0.for i in range(len(indegrees)):if not indegrees[i]: queue.append(i)# BFS TopSort.while queue:pre = queue.popleft()numCourses -= 1for cur in adjacency[pre]:indegrees[cur] -= 1if not indegrees[cur]: queue.append(cur)return not numCourses

时间复杂度:O(n + m)
空间复杂度:O(n + m) 为建立邻接表所需额外空间,adjacency 长度为 N ,并存储 M 条临边的数据。

解题思路二:深度优先遍历

在这里插入图片描述

class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:def dfs(i, adjacency, flags):if flags[i] == -1: return Trueif flags[i] == 1: return Falseflags[i] = 1for j in adjacency[i]:if not dfs(j, adjacency, flags): return Falseflags[i] = -1return Trueadjacency = [[] for _ in range(numCourses)]flags = [0 for _ in range(numCourses)]for cur, pre in prerequisites:adjacency[pre].append(cur)for i in range(numCourses):if not dfs(i, adjacency, flags): return Falsereturn True

时间复杂度:O(n + m)
空间复杂度:O(n + m) 为建立邻接表所需额外空间,adjacency 长度为 N ,并存储 M 条临边的数据。
https://leetcode.cn/problems/course-schedule/solutions/18806/course-schedule-tuo-bu-pai-xu-bfsdfsliang-chong-fa

解题思路三:广度优先搜索(就是拓扑排序)

class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:edges = collections.defaultdict(list)indeg = [0] * numCoursesfor info in prerequisites:edges[info[1]].append(info[0])indeg[info[0]] += 1q = collections.deque([u for u in range(numCourses) if indeg[u] == 0])visited = 0while q:visited += 1u = q.popleft()for v in edges[u]:indeg[v] -= 1if indeg[v] == 0:q.append(v)return visited == numCourses

时间复杂度:O(n + m)
空间复杂度:O(n + m) 为建立邻接表所需额外空间,adjacency 长度为 N ,并存储 M 条临边的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/593585.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pillow教程10:设计博文的文字背景封面图,再也不担心找不到不素材了

---------------Pillow教程集合--------------- Python项目18&#xff1a;使用Pillow模块&#xff0c;随机生成4位数的图片验证码 Python教程93&#xff1a;初识Pillow模块&#xff08;创建Image对象查看属性图片的保存与缩放&#xff09; Pillow教程02&#xff1a;图片的裁…

C# WPF编程-元素绑定

C# WPF编程-元素绑定 将元素绑定到一起绑定表达式绑定错误绑定模式代码创建绑定移除绑定使用代码检索绑定多绑定绑定更新绑定延时 绑定到非元素对象Source属性RelativeSource属性DataContent属性 数据绑定是一种关系&#xff0c;该关系告诉WPF从源对象提取一下信息&#xff0c;…

JAVA八股--redis

JAVA八股--redis 如何保证Redis和数据库数据一致性redisson实现的分布式锁的主从一致性Redis脑裂现象及解决方案介绍I/O多路复用模型undo log 和 redo log&#xff08;没掌握MyISAM 和 InnoDB 有什么区别&#xff1f; 如何保证Redis和数据库数据一致性 关于异步通知中消息队列…

高并发高性能接口中,异步打印并采集业务日志的实现方案

一、背景 高并发接口中&#xff0c;为了提高接口的高性能&#xff0c;在需要保存审计及操作记录的时候&#xff0c;往往有以下常见方案&#xff1a; 保存到redis数据库异步保存到mysql/mongodb/es等数据库logger打印业务日志&#xff0c;采集与展示则交由elk模块 对于第一种…

吃豆豆 经典的区间DP 好题典题

这里很巧妙的注意一点是&#xff0c;你最后要把所有的豆子都吃掉&#xff0c;所以你只要看你多增加的尽量的少就好了 然后维护一段区间&#xff0c;表示的是吃掉这段区间里面的所有豆子的最小代价&#xff0c;然后发现最后一个是左端点或者右端点 你吃一段新的区间的同时会把…

设计模式总结-面向对象设计原则

面向对象设计原则 面向对象设计原则简介单一职责原则单一职责原则定义单一职责原则分析单一职责原则实例 开闭原则开闭原则定义开闭原则分析开闭原则实例 里氏代换原则里氏代换原则定义里氏代换原则分析 依赖倒转原则依赖倒转原则定义依赖倒转原则分析依赖倒转原则实例 接口隔离…

下载图片的程序

import requests from lxml import etree class TianJiPlc: def init(self): self.url_home_page“https://wap.yesky.com/pic/” self.headers{‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Sa…

笔记本电脑win7 Wireless-AC 7265连不上wifi6

1.背景介绍 旧路由器连接人数有限&#xff0c;老旧&#xff0c;信号不稳定更换了新路由器&#xff0c;如 TL-XDR5430易展版用户电脑连不上新的WIFI网络了&#xff0c;比较着急 核心问题&#xff1a;有效解决笔记本连接wifi上网问题&#xff0c;方法不限 2.环境信息 Windows…

设计模式——建造者模式03

工厂模式注重直接生产一个对象&#xff0c;而建造者模式 注重一个复杂对象是如何组成的&#xff08;过程&#xff09;&#xff0c;在生产每个组件时&#xff0c;满足单一原则&#xff0c;实现了业务拆分。 设计模式&#xff0c;一定要敲代码理解 组件抽象 public interface …

C++ 注册Nacos

下载源码&#xff1a; git clone GitHub - nacos-group/nacos-sdk-cpp: C client for Nacos 编译源码 cd nacos-sdk-cpp cmake . make 生成库文件 在nacos-sdk-cpp 下 注册nacos 将include 和libnacos-cli.so libnacos-cli-static.a 放入你的工程 如果Nacos服务地址:…

AI Kimi:帮助教师做好试卷命题

原文&#xff1a;https://www.toutiao.com/article/7353661304307778083/?log_fromcfd0a50014034_1712243146922 最近&#xff0c;Kimichat工具很火。这款软件不仅仅是一个聊天和阅读工具&#xff0c;还是一个强大的教学辅助工具。作为一位教师&#xff0c;尝试使用Kimichat&…

HTML:框架

案例&#xff1a; <frameset cols"5%,*" ><frame src"left_frame.html"><frame src"right_frame.html"> </frameset> 一、<frameset>标签 <frameset>标签&#xff1a;称为框架标记&#xff0c;将一个HTML…