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

Python每日一练(20230505) 课程表 Course Schedule III/IV

目录

3. 课程表 Course Schedule III

4. 课程表 Course Schedule IV

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


3. 课程表 Course Schedule III

这里有 n 门不同的在线课程,按从 1 到 n 编号。给你一个数组 courses ,其中 courses[i] = [durationi, lastDayi] 表示第 i 门课将会 持续 上 durationi 天课,并且必须在不晚于 lastDayi 的时候完成。

你的学期从第 1 天开始。且不能同时修读两门及两门以上的课程。

返回你最多可以修读的课程数目。

示例 1:

输入:courses = [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
输出:3
解释:
这里一共有 4 门课程,但是你最多可以修 3 门:
首先,修第 1 门课,耗费 100 天,在第 100 天完成,在第 101 天开始下门课。
第二,修第 3 门课,耗费 1000 天,在第 1100 天完成,在第 1101 天开始下门课程。
第三,修第 2 门课,耗时 200 天,在第 1300 天完成。
第 4 门课现在不能修,因为将会在第 3300 天完成它,这已经超出了关闭日期。

示例 2:

输入:courses = [[1,2]]
输出:1

示例 3:

输入:courses = [[3,2],[4,3]]
输出:0

提示:

  • 1 <= courses.length <= 10^4
  • 1 <= durationi, lastDayi <= 10^4

代码: 贪心算法

package main

import (
	"fmt"
	"sort"
)

func scheduleCourse(courses [][]int) int {
	// 按照截止日期升序排序
	sort.Slice(courses, func(i, j int) bool {
		return courses[i][1] < courses[j][1]
	})

	time := 0
	selected := make([][]int, 0)
	for _, c := range courses {
		if time+c[0] <= c[1] {
			selected = append(selected, []int{c[0], c[1]})
			time += c[0]
			sort.Slice(selected, func(i, j int) bool {
				return selected[i][0] > selected[j][0]
			})
		} else if len(selected) > 0 && c[0] < selected[0][0] {
			time += c[0] - selected[0][0]
			selected[0] = []int{c[0], c[1]}
			sort.Slice(selected, func(i, j int) bool {
				return selected[i][0] > selected[j][0]
			})
		}
	}

	return len(selected)
}

func main() {
	courses := [][]int{{100, 200}, {200, 1300}, {1000, 1250}, {2000, 3200}}
	fmt.Println(scheduleCourse(courses))
	courses = [][]int{{1, 2}}
	fmt.Println(scheduleCourse(courses))
}

输出:

3
1


4. 课程表 Course Schedule IV

你总共需要上 numCourses 门课,课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite ,其中 prerequisites[i] = [ai, bi] 表示如果你想选 bi 课程,你 必须 先选 ai 课程。

  • 有的课会有直接的先修课程,比如如果想上课程 1 ,你必须先上课程 0 ,那么会以 [0,1] 数对的形式给出先修课程数对。

先决条件也可以是 间接 的。如果课程 a 是课程 b 的先决条件,课程 b 是课程 c 的先决条件,那么课程 a 就是课程 c 的先决条件。

你也得到一个数组 queries ,其中 queries[j] = [uj, vj]。对于第 j 个查询,您应该回答课程 uj 是否是课程 vj 的先决条件。

返回一个布尔数组 answer ,其中 answer[j] 是第 j 个查询的答案。

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]], queries = [[0,1],[1,0]]
输出:[false,true]
解释:课程 0 不是课程 1 的先修课程,但课程 1 是课程 0 的先修课程。

示例 2:

输入:numCourses = 2, prerequisites = [], queries = [[1,0],[0,1]]
输出:[false,false]
解释:没有先修课程对,所以每门课程之间是独立的。

示例 3:

输入:numCourses = 3, prerequisites = [[1,2],[1,0],[2,0]], queries = [[1,0],[1,2]]
输出:[true,true]

提示:

  • 2 <= numCourses <= 100
  • 0 <= prerequisites.length <= (numCourses * (numCourses - 1) / 2)
  • prerequisites[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi
  • 每一对 [ai, bi] 都 不同
  • 先修课程图中没有环。
  • 0 <= ui, vi <= n - 1
  • ui != vi

代码:

package main

import "fmt"

func checkIfPrerequisite(numCourses int, prerequisites [][]int, queries [][]int) []bool {
	// 构建课程图
	n := numCourses
	graph := make([][]int, n)
	inDegree := make([]int, n)
	for _, p := range prerequisites {
		ai, bi := p[0], p[1]
		graph[ai] = append(graph[ai], bi)
		inDegree[bi]++
	}

	// BFS 拓扑排序
	queue := make([]int, 0)
	for i := 0; i < n; i++ {
		if inDegree[i] == 0 {
			queue = append(queue, i)
		}
	}
	successors := make([][]int, n)
	for len(queue) > 0 {
		node := queue[0]
		queue = queue[1:]
		for _, neighbor := range graph[node] {
			inDegree[neighbor]--
			if inDegree[neighbor] == 0 {
				queue = append(queue, neighbor)
			}
			// 记录 successor 节点
			successors[node] = append(successors[node], neighbor)
			for _, s := range successors[neighbor] {
				successors[node] = append(successors[node], s)
			}
		}
	}

	// 对每个查询进行检查
	result := make([]bool, len(queries))
	for i, q := range queries {
		ui, vi := q[0], q[1]
		for _, s := range successors[ui] {
			if s == vi {
				result[i] = true
				break
			}
		}
	}
	return result
}

func main() {
	numCourses := 2
	prerequisites := [][]int{{1, 0}}
	queries := [][]int{{0, 1}, {1, 0}}
	fmt.Println(checkIfPrerequisite(numCourses, prerequisites, queries))
	prerequisites = [][]int{}
	queries = [][]int{{1, 0}, {0, 1}}
	fmt.Println(checkIfPrerequisite(numCourses, prerequisites, queries))
}

输出:

[false true]
[false false]


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


http://www.kler.cn/a/16916.html

相关文章:

  • 基于springboot的汽车租赁管理系统的设计与实现
  • C 语言 【模拟实现内存库函数】
  • 【数据结构与算法】第12课—数据结构之归并排序
  • 学习记录:js算法(九十二):克隆图
  • C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
  • jmeter常用配置元件介绍总结之后置处理器
  • Java 中的集合框架有哪些?(十四)
  • Leetcode刷题日志2.0
  • 【QT】 Qt高级——Qt自定义标题栏
  • 为什么说网络安全行业是IT行业最后的红利?
  • 【计算机是怎么跑起来的】基础:计算机三大原则
  • 前端架构师-week4-Node多进程开发入门
  • 《用于准确连续非侵入性血压监测的心跳内生物标志物》阅读笔记
  • 3分钟快速了解mysql数据导入到es
  • 【OMNET++】V2X仿真
  • 【Mac教学】如何打开macOS 的最大权限
  • 密码学【java语言】初探究
  • python面向对象三大特性详解 - 封装 继承 多态
  • 第四十八章 管理镜像 - 将备份降级为 DR 异步
  • Three.js--》模型材质与纹理的使用
  • 如何编写高质量代码
  • CentOS7 安装MySQL8
  • 第16章 指令级并行与超标量处理器
  • java获取文件名后缀方法
  • 分布式光伏发电大规模应用,运维难题如何解?
  • 网络应用基础 ——(2023新星计划文章一)