当前位置: 首页 > news >正文

做鸭子的网站友情链接2598

做鸭子的网站,友情链接2598,网站建设主要工作由哪些,国家级示范校建设专题网站Python算法题集_课程表 题207:课程表1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【循环递归全算】2) 改进版一【循环递归缓存】3) 改进版二【循环递归缓存反向计算】4) 改进版三【迭代剥离计数器检测】 4. 最优算法5. 相关资源 本…

 Python算法题集_课程表

  • 题207:课程表
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【循环+递归+全算】
    • 2) 改进版一【循环+递归+缓存】
    • 3) 改进版二【循环+递归+缓存+反向计算】
    • 4) 改进版三【迭代剥离+计数器检测】
  • 4. 最优算法
  • 5. 相关资源

本文为Python算法题集之一的代码示例

题207:课程表

1. 示例说明

你这个学期必须选修 numCourses 门课程,记为 0numCourses - 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] 中的所有课程对 互不相同

2. 题目解析

- 题意分解

  1. 本题是计算是否会出现无法学习的课程,这种课程的特点是前置课程出现环路,比如A课程的前置课程B的前置课程为A课程
  2. 本题必须进行课程遍历,每个课程都需要检测是否出现环路
  3. 基本的设计思路是循环+递归,循环遍历课程,递归检测环路

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 如果一个课程已经检测没有出现环路,则前置课程检测到此课程就不用继续检测下去,减少计算量

    2. 可以研究迭代法实现科目检测


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题超时测试用例较难生成,已经保存为文本文件,本次测试结果详见章节【最优算法】,测试用例文件包含在【相关资源】中

3. 代码展开

1) 标准求解【循环+递归+全算】

循环遍历课程,递归检测环路,能算尽算,不出所料,功能测试就已超时

页面功能测试,未能通关,超时失败在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def canFinish_base(self, numCourses, prerequisites):list_graph = [[] for x in range(numCourses)]for a, b in prerequisites:list_graph[a].append(b)def dfs_checkring(visited, pres):if not pres:return Trueresult = Truefor course in pres:if course in visited:return Falseresult &= dfs_checkring(visited + [course], list_graph[course])return resultreturn all(dfs_checkring([i], pres) for i, pres in enumerate(list_graph))print(f'prerequisites count of the Courses = {len(check_prerequisites)}')
result = cfp.getTimeMemoryStr(Solution.canFinish_base, aSolution, 50000, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
prerequisites count of the Courses = 49999
函数 canFinish_base 的运行时间为 50813.51 ms;内存使用量为 7264.00 KB 执行结果 = True

2) 改进版一【循环+递归+缓存】

循环遍历课程,递归检测环路,缓存已经计算的课程环路结果

页面功能测试,勉强通过,超过11%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def canFinish_ext1(self, numCourses: int, prerequisites):list_graph = [[] for x in range(numCourses)]for a, b in prerequisites:list_graph[a].append(b)learned = [0] * numCoursesdef dfs_checkring(visited, pres):if not pres:return Trueresult = Truefor course in pres:if course in visited:return Falseif learned[course] > 0:continuelearned[course] = 1result &= dfs_checkring(visited + [course], list_graph[course])return resultfor iIdx, pres in enumerate(list_graph):if learned[iIdx] > 0:continueresult = dfs_checkring([iIdx], pres)if not result:return Falselearned[iIdx] = 1return Trueprint(f'prerequisites count of the Courses = {len(check_prerequisites)}')
result = cfp.getTimeMemoryStr(Solution.canFinish_base, aSolution, 50000, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
prerequisites count of the Courses = 49999
函数 canFinish_ext1 的运行时间为 66.02 ms;内存使用量为 6112.00 KB 执行结果 = True

3) 改进版二【循环+递归+缓存+反向计算】

循环遍历课程,递归检测环路,但是检测环路修改为从前置科目开始计算此科目的后置科目是否出现环路

页面功能测试,性能良好,超过88%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def canFinish_ext2(self, numCourses, prerequisites):def dfs_checkring(iIdx, list_graph, ringflags):if ringflags[iIdx] == -1:return Trueif ringflags[iIdx] == 1:return Falseringflags[iIdx] = 1for jIdx in list_graph[iIdx]:if not dfs_checkring(jIdx, list_graph, ringflags):return Falseringflags[iIdx] = -1return Truelist_graph = [[] for x in range(numCourses) ]list_flags = [0 for x in range(numCourses)]for a, b in prerequisites:list_graph[b].append(a)for iIdx in range(numCourses):if not dfs_checkring(iIdx, list_graph, list_flags):return Falsereturn Trueprint(f'prerequisites count of the Courses = {len(check_prerequisites)}')
result = cfp.getTimeMemoryStr(Solution.canFinish_ext2, aSolution, 50000, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
prerequisites count of the Courses = 49999
函数 canFinish_ext2 的运行时间为 80.01 ms;内存使用量为 520.00 KB 执行结果 = True

4) 改进版三【迭代剥离+计数器检测】

特殊的迭代思路

  1. 首先必须存在没有任何前置的科目,否则第一门科目都没有办法学习,直接返回False;由此可建立没有前置科目的队列
  2. 迭代没有前置科目的队列,逐步剥离此科目后置科目的计数器,如果后置科目的前置计数器清零,则作为无前置科目放入队列
  3. 迭代完毕后检测有效科目数量是否达标

页面功能测试,马马虎虎,超过55%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def canFinish_ext3(self, numCourses, prerequisites):from collections import deque, defaultdictdeque_graph = defaultdict(list)learned = [0] * numCoursesfor course, visited in prerequisites:deque_graph[visited].append(course)learned[course] += 1queue = deque([x for x in range(numCourses) if learned[x] == 0])processed_courses = 0while queue:visited = queue.popleft()processed_courses += 1for course in deque_graph[visited]:learned[course] -= 1if learned[course] == 0:queue.append(course)return processed_courses >= numCoursesprint(f'prerequisites count of the Courses = {len(check_prerequisites)}')
result = cfp.getTimeMemoryStr(Solution.canFinish_ext3, aSolution, 50000, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
prerequisites count of the Courses = 49999
函数 canFinish_ext3 的运行时间为 84.02 ms;内存使用量为 584.00 KB 执行结果 = True

4. 最优算法

根据本地日志分析,最优算法为第2种方式【循环+递归+缓存】canFinish_ext1

由于四段代码思路一致,主要是使用的数据结构不同,因此经验推出以下结论:

  1. 在作为队列使用时【先进先出】,deque性能远远高于list
  2. 迭代器循环优于循环中进行异常检测
  3. 下标循环和枚举循环性能基本一致
inumCourses = 50000
aSolution = Solution()
testcase_big = open(r'testcase/hot53_big5W.txt', mode='r', encoding='utf-8').read()
testcase_big = testcase_big.replace('[', '')
tmpItems = testcase_big.split(']')
check_pre = []
for aItem in tmpItems:tmpcurpre = aItem.split(',')if len(tmpcurpre) == 2:check_pre.append([int(tmpcurpre[0]), int(tmpcurpre[1])])
check_prerequisites = check_pre
print(f'prerequisites count of the Courses = {len(check_prerequisites)}')
result = cfp.getTimeMemoryStr(Solution.canFinish_base, aSolution, inumCourses, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))
result = cfp.getTimeMemoryStr(Solution.canFinish_ext1, aSolution, inumCourses, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))
result = cfp.getTimeMemoryStr(Solution.canFinish_ext2, aSolution, inumCourses, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))
result = cfp.getTimeMemoryStr(Solution.canFinish_ext3, aSolution, inumCourses, check_prerequisites)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 算法本地速度实测比较
prerequisites count of the Courses = 49999
函数 canFinish_base 的运行时间为 50813.51 ms;内存使用量为 7264.00 KB 执行结果 = True
函数 canFinish_ext1 的运行时间为 66.02 ms;内存使用量为 6112.00 KB 执行结果 = True
函数 canFinish_ext2 的运行时间为 80.01 ms;内存使用量为 520.00 KB 执行结果 = True
函数 canFinish_ext3 的运行时间为 84.02 ms;内存使用量为 584.00 KB 执行结果 = True

5. 相关资源

本文代码已上传到CSDN,地址:Python算法题源代码_LeetCode(力扣)_课程表

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

http://www.tj-hxxt.cn/news/109606.html

相关文章:

  • 个人能否做网站内容营销案例
  • 公司网站模板源代码网络网站推广选择乐云seo
  • 网站上滚动图片如何做公司网站的作用
  • 动态网站登录加注册怎么做2345网址导航怎么卸载
  • 网站建设合同的性质网络公司网页设计
  • 网站建设怎样容易上海企业推广
  • 买服务器做网站凡科建站代理
  • 北京网站设计招聘国家反诈中心app下载
  • 免费营销型网站建设线下推广活动策划方案
  • 上海网站建设中seo友情链接
  • 如何建立网站销售平台西安疫情最新情况
  • 球场 技术支持 东莞网站建设怎么样进行网络推广
  • 太原中企动力网站建设如何让网站被百度收录
  • 专业返利网站开发营销软件哪个好
  • 东莞中小企业网站建设最近的新闻大事20条
  • 影视网站策划书app推广拉新接单平台
  • 医院网站建设方案青岛卓信aso优化方法
  • 做营销型网站公司重庆森林经典台词梁朝伟
  • 工作表现情况怎么写宁波seo深度优化平台
  • 专业的营销型网站建设网上销售
  • wordpress访问私密帖子青岛百度推广seo价格
  • 开发网站开发工程师招聘要求网络推广营销策划方案
  • 做除尘骨架的网站宁波网站推广
  • 国际顶级中文域名注册推荐一个seo优化软件
  • 网站备案了有什么好处百度识图网页版在线
  • 电子商务网站建设书籍搜关键词网站
  • 网站个人备案做论坛免费刷粉网站推广
  • 个人网站备案后可以做行业内容吗百度怎么推广产品
  • 织梦 去掉我的网站网站模板设计
  • 番禺做网站哪家专业北京网站推广排名