课程表II(力扣、210)

这是一个关于课程选择的问题,需要根据先修课程的条件确定学习顺序。通过拓扑排序方法,可以找到完成所有课程的一种正确顺序。示例展示了如何在存在先修课程的情况下进行课程安排。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。

可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

示例 1:

输入: 2, [[1,0]]
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
示例 2:

输入: 4, [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule-ii
思路:这道题是图的拓扑排序问题。对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。题目中给出的图的表示方法是一个有序对,用于表示图中的边。如,示例1中的[[1,0]]表示的就是从0出发到1的一条有向边,即<0,1>。然后利用拓扑排序的思想就可以完成。
代码:

//代码使用的是队列完成拓扑排序
int front;
int rear;
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize)
{
    front=rear=0;
    int *indegree,*res,*queue;
    int i,cnt=0,k,ind,pre;
    indegree=(int*)malloc((numCourses+1)*sizeof(int));
    res=(int*)malloc((numCourses+1)*sizeof(int));
    queue=(int*)malloc((numCourses+1)*sizeof(int));
    *returnSize=0;
    for(i=0;i<numCourses;i++)
        indegree[i]=0;
    /*将各顶点的入度记录在indegree数组中,
    用下标表示顶点信息,初始化数组*/
    for(i=0;i<prerequisitesSize;i++)
    {
        ind=prerequisites[i][0];
        indegree[ind]++;//记录顶点的入度
    }
    for(i=0;i<numCourses;i++)
        if(indegree[i]==0)
            queue[rear++]=i;//将入度为0的顶点入队
    while(front!=rear)
    {
        pre=queue[front++];//第一个入度为0的顶点出队
        res[*returnSize]=pre;
        cnt++;
        (*returnSize)++;
        for(i=0;i<prerequisitesSize;i++)
        {
            k=prerequisites[i][1];
            if(pre==k)
                if(--indegree[prerequisites[i][0]]==0)
                    queue[rear++]=prerequisites[i][0];
        }
    /*遇到入度为0的顶点后,在队列中删除该顶点,
    并该顶点的出弧所连的顶点入度减1,若入度减1后该
    顶点入度恰好减为0,则继续入队*/
    }
    if(cnt<numCourses)//有环或者有非连通部分,不符合题意
        *returnSize=0;
    return res;
}
### 力扣热门100题列表 力扣(LeetCode)上的热门题目通常是指那些被广泛讨论、高频面试或者具有较高难度的题目。这些题目涵盖了数据结构和算法的核心知识点,适合用来提升编程能力和解决实际问题的能力。 以下是基于社区反馈整理的部分 **LeetCode Hot 100 Problems List**: #### 数组与字符串 1. Two Sum (两数之和)[^1] 2. Longest Substring Without Repeating Characters (无重复字符的最长子串)[^2] 3. Median of Two Sorted Arrays (两个有序数组的中位数)[^1] 4. Container With Most Water (盛最多水的容器)[^2] #### 链表 5. Reverse Linked List (反转链表) 6. Merge Two Sorted Lists (合并两个有序链表) 7. Remove Nth Node From End of List (删除倒数第N个节点) 8. Linked List Cycle II (环形链表II) #### 堆栈与队列 9. Valid Parentheses (有效的括号) 10. Min Stack (最小栈) 11. Sliding Window Maximum (滑动窗口最大值)[^2] #### 树与二叉树 12. Binary Tree Inorder Traversal (二叉树的中序遍历) 13. Validate Binary Search Tree (验证二叉搜索树) 14. Same Tree (相同的树) 15. Serialize and Deserialize Binary Tree (序列化与反序列化二叉树) #### 图论 16. Number of Islands (岛屿数量) 17. Course Schedule (课程表) 18. Clone Graph (克隆图) #### 排序与搜索 19. Find First and Last Position of Element in Sorted Array (在排序数组中查找元素的第一个和最后一个位置) 20. Search a 2D Matrix (二维矩阵搜索) 21. K Closest Points to Origin (最接近原点的K个点) #### 动态规划 22. Climbing Stairs (爬楼梯) 23. House Robber (打家劫舍)[^1] 24. Coin Change (零钱兑换) 25. Unique Paths (不同路径) #### 贪心算法 26. Jump Game (跳跃游戏)[^1] 27. Non-overlapping Intervals (无重叠区间) 28. Best Time to Buy and Sell Stock (买卖股票的最佳时机)[^1] #### 字符串匹配与处理 29. Implement strStr() (实现strStr()) 30. Longest Consecutive Sequence (最长连续序列) 31. Group Anagrams (分组异位词) --- ### 示例代码片段 以下是一个关于动态规划的经典例子——`Climbing Stairs` 的 Python 实现: ```python class Solution: def climbStairs(self, n: int) -> int: if n == 1 or n == 2: return n dp = [0] * (n + 1) dp[1], dp[2] = 1, 2 for i in range(3, n + 1): dp[i] = dp[i - 1] + dp[i - 2] return dp[n] ``` 上述代码通过动态规划的方式解决了 `Climbing Stairs` 问题,时间复杂度为 \(O(n)\),空间复杂度同样为 \(O(n)\)[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值