Java拓扑排序知识点(含面试大厂题和源码)

devtools/2024/9/24 12:24:08/

拓扑排序是针对有向无环图(DAG)的一种排序算法,它将图中的所有顶点排成一个线性序列,使得对于任何一条有向边 U -> V,顶点 U 都在顶点 V 的前面。拓扑排序是许多算法的前置步骤,如课程规划、工程任务调度、依赖性解析等。

拓扑排序的算法步骤:

  1. 计算入度:计算图中所有顶点的入度(指向该顶点的边的数量)。
  2. 初始化一个空栈:用于存放排序结果。
  3. 遍历所有顶点
    • 从入度为0的顶点开始,将其加入栈中,并将该顶点标记为已访问。
    • 从当前顶点出发,遍历其所有邻接点,将每个邻接点的入度减1。如果邻接点的入度变为0,则重复上述步骤。
  4. 重复步骤3:直到所有顶点都被访问过。
  5. 输出栈中的顶点:栈中的顶点序列即为拓扑排序结果。

拓扑排序的Java实现:

java">import java.util.*;public class TopologicalSort {public List<Integer> topoSort(int V, int[][] edges) {List<Integer> result = new ArrayList<>();int[] inDegree = new int[V];// 初始化入度数组for (int[] edge : edges) {inDegree[edge[1]]++;}// 使用队列存储所有入度为0的顶点Queue<Integer> queue = new LinkedList<>();for (int i = 0; i < V; i++) {if (inDegree[i] == 0) {queue.offer(i);}}while (!queue.isEmpty()) {int current = queue.poll();result.add(current);for (int[] edge : edges) {if (edge[0] == current) {int next = edge[1];inDegree[next]--;if (inDegree[next] == 0) {queue.offer(next);}}}}return result;}public static void main(String[] args) {TopologicalSort topoSort = new TopologicalSort();int V = 6;int[][] edges = {{5, 2},{5, 0},{4, 0},{4, 1},{2, 3},{3, 1}};List<Integer> result = topoSort. topoSort(V, edges);System.out.println("Topological Sort: " + result);}
}

面试中,拓扑排序是一个重要的知识点,它考察应聘者对图算法的理解和算法实现能力。通过实现拓扑排序,可以展示你对图算法和排序算法的掌握程度。希望这些知识点和示例代码能够帮助你更好地准备面试!拓扑排序是图算法中的一个常见问题,经常出现在大厂的面试中。以下是三道与拓扑排序相关的面试题目,以及相应的Java源码实现。

题目 1:课程安排问题

描述
给定 n 门课程和一个先决条件列表,每个课程都有一个先决条件,表示必须先修的课程。请为这些课程安排学习顺序。

示例

输入: n = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出: [0, 1, 2, 3] 或 [0, 2, 1, 3](答案不唯一)

Java 源码

java">import java.util.ArrayList;
import java.util.List;public class CourseSchedule {public int[] findOrder(int n, int[][] prerequisites) {int[] inDegree = new int[n];List<List<Integer>> graph = new ArrayList<>(n);for (int i = 0; i < n; i++) {graph.add(new ArrayList<>());}for (int[] edge : prerequisites) {graph.get(edge[1]).add(edge[0]);inDegree[edge[0]]++;}List<Integer> zeroInDegree = new ArrayList<>();for (int i = 0; i < n; i++) {if (inDegree[i] == 0) {zeroInDegree.add(i);}}List<Integer> order = new ArrayList<>();while (!zeroInDegree.isEmpty()) {int course = zeroInDegree.remove(0);order.add(course);for (int next : graph.get(course)) {if (--inDegree[next] == 0) {zeroInDegree.add(next);}}}return order.size() == n ? order.stream().mapToInt(i -> i).toArray() : new int[]{};}public static void main(String[] args) {CourseSchedule solution = new CourseSchedule();int n = 4;int[][] prerequisites = {{1, 0}, {2, 0}, {3, 1}, {3, 2}};int[] result = solution.findOrder(n, prerequisites);System.out.println("Course order: " + Arrays.toString(result));}
}

题目 2:项目任务顺序

描述
给定一个项目,包含多个任务,以及任务之间的依赖关系。每个任务只能等所有依赖它的任务完成后才能开始。请为这些任务安排执行顺序。

示例

输入: n = 5, edges = [[1,0],[2,0],[3,1],[3,2],[4,0],[4,3],[5, 1],[5, 2],[5, 3],[5, 4]]
输出: [0, 1, 2, 3, 4] 或其他有效的拓扑排序结果

Java 源码

java">import java.util.*;public class ProjectScheduling {public List<Integer> criticalPath(int n, int[][] edges) {List<List<Integer>> graph = new ArrayList<>();int[] inDegree = new int[n];for (int i = 0; i < n; i++) {graph.add(new ArrayList<>());}for (int[] edge : edges) {graph.get(edge[1]).add(edge[0]);inDegree[edge[0]]++;}Queue<Integer> queue = new LinkedList<>();for (int i = 0; i < n; i++) {if (inDegree[i] == 0) {queue.offer(i);}}List<Integer> order = new ArrayList<>();while (!queue.isEmpty()) {int task = queue.poll();order.add(task);for (int next : graph.get(task)) {if (--inDegree[next] == 0) {queue.offer(next);}}}return order;}public static void main(String[] args) {ProjectScheduling solution = new ProjectScheduling();int n = 5;int[][] edges = {{1, 0}, {2, 0}, {3, 1}, {3, 2}, {4, 0}, {4, 3}, {5, 1}, {5, 2}, {5, 3}, {5, 4}};List<Integer> result = solution.criticalPath(n, edges);System.out.println("Task execution order: " + result);}
}

题目 3:最长无环子序列

描述
给定一个整数序列,找到一个最长的无环子序列。无环子序列是指子序列中的任意两个数字之间没有拓扑排序关系。

示例

输入: [2, 6, 4, 1, 5, 3]
输出: 3

Java 源码

java">import java.util.*;public class LongestAcyclicSubsequence {public int longestUncrossed(int[] arr) {int n = arr.length;int[] dp = new int[n];int[] tails = new int[n];Arrays.fill(tails, -1);dp[0] = 1;for (int i = 1; i < n; i++) {int max = 0;int prev = -1;for (int j = 0; j < i; j++) {if (arr[j] < arr[i]) {if (tails[j] == -1 || tails[j] > prev) {max = Math.max(max, dp[j]);}} else if (arr[j] == arr[i] && tails[j] != -1) {prev = Math.max(prev, dp[j]);}}dp[i] = max + 1;tails[i] = max;}return Arrays.stream(dp).max().getAsInt();}public static void main(String[] args) {LongestAcyclicSubsequence solution = new LongestAcyclicSubsequence();int[] arr = {2, 6, 4, 1, 5, 3};int result = solution.longestUncrossed(arr);System.out.println("Length of longest uncrossed subsequence: " + result);}
}

这些题目和源码展示了拓扑排序在解决实际问题中的应用。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试


http://www.ppmy.cn/devtools/8769.html

相关文章

信源信息数智能化招采平台V7.0全新升级

信源信息凭借18年以来在招采领域累积的深厚行业经验和业务洞察&#xff0c;数智化招采平台经历V1.0到V7.0的迭代升级&#xff0c;赋能更多政企用户数字化转型&#xff0c;实现效率提升、管理升级、业务发展&#xff0c;进而推动新质生产力的释放。 技术创新赋能&#xff0c;打…

4.15 day6 ARM

uart.c #include "uart4.h" void uart4_config() {RCC->MP_AHB4ENSETR | (0X1 << 6);//&#xff27;RCC->MP_AHB4ENSETR | (0X1 << 1);//BRCC->MP_APB1ENSETR | (0X1 << 16);//UART4 //管脚复用GPIOG->MODER & (~(0X3 << …

网络安全之反弹Shell

网络安全之反弹Shell 在网络安全和渗透测试领域&#xff0c;“正向Shell”&#xff08;Forward Shell&#xff09;和"反向Shell"&#xff08;Reverse Shell&#xff09;是两种常用的技术手段&#xff0c;用于建立远程访问目标计算机的会话。这两种技术都可以让攻击者…

鸿蒙开发实例:【配置OpenHarmony SDK】

配置OpenHarmony SDK 在设置OpenHarmony应用开发环境时&#xff0c;需要开发者在DevEco Studio中配置对应的SDK信息。 说明&#xff1a; 请注意&#xff0c;OpenHarmony SDK版本精简了部分工具链&#xff0c;因此不适用于HarmonyOS应用开发。 前提条件 已下载并安装好DevEco …

react ui design

react ui design 欢迎使用Markdown编辑器 欢迎使用Markdown编辑器 yarn create vite my-react-app --template react-tsnpx storybooklatest inityarn add --dev commitlint/{cli,config-conventional}echo "export default { extends: [commitlint/config-conventional]…

Gitlab相关,【推送项目】

推送现有文件夹 cd existing_folder git init git remote add origin git10.200.5.138:taps/archetech.git git add . git commit -m "Initial commit"git pull -u origin master另外 git branch -b new_branch //创建本地分支并切换 git branch //查看本地分支 …

NTP授时服务器(GPS授时器)在DCS系统应用

NTP授时服务器&#xff08;GPS授时器&#xff09;在DCS系统应用 前言 随着计算机和网络通信技术的飞速发展&#xff0c;各行业自动化系统数字化、网络化的时代已经到来。这一方面为各控制和信息系统之间的数据交换、分析和应用提供了更好的平台、另一方面对各种实时和历史数据…

Vue项目学习(一)-SQL闯关

Hello , 我是小恒不会java。今天来阅读一个Vue纯前端项目--SQL在线闯关 进步的方法除了文档书籍视频&#xff0c;学会阅读源代码&#xff0c;从代码中学会解决需求的方法也是必要的 已部署完成&#xff0c;在线体验&#xff1a;http://sql.yunduanjianzhan.cn 背景 简介 闯…