LeetCode Course Schedule Topological Sorting(golang&java)

本文介绍LeetCode的课程安排问题,通过拓扑排序判断课程预设条件是否构成环,从而确定课程能否成功安排。分析过程包括将问题转化为判断是否为有向无环图(DAG),并通过拓扑排序原理进行分析。最后提供了Golang和Java两种语言的代码实现。
摘要由CSDN通过智能技术生成

Problem
在这里插入图片描述
Basics
Topological Sorting
To perform Topological ordering of a Directed Acyclic Graph (DAG)G, all vertices in G are arranged into a linear sequence, making any pair of vertices u and v in the Graph. If the edge <u,v> E(G), then u appears before v in the linear sequence. Normally, such a linear sequence is referred to as a sequence satisfying Topological Order, short for Topological sequence

In graph theory, if a directed graph to set off from a vertex after several side back to that point, then the graph is a directed acyclic graph (DAG) because there is a point to the picture after two route to another point may not form a ring, so directed acyclic graph are not necessarily as tree, but any directed tree are directed acyclic graph

The topology sorting algorithm of topology sequence constructed by AOV network mainly performs the following two steps in a loop until there is no vertex with an entry degree of 0
1.Select a vertex with an input of 0 and output it
2.Deletes this vertex and all outgoing edges from the net
After the loop is completed, if the number of vertices output is less than the number of vertices in the network, loop information is output; otherwise, the output vertex sequence is a topology sequence

Analysis Process
1.This problem can be reduced to: is the course schedule a directed acyclic graph (DAG), that is, the courses stipulate preconditions, but cannot constitute any loop, otherwise the course preconditions will not be valid

2.The idea is to judge whether this course arrangement diagram is a directed acyclic graph (DAG) by topological sorting principle: sort the vertices of DAG, so that for each directed edge(u,v), there is u (in the sorting record) before v, which can also be understood as v for a point, only when all the source points of v appear, v can appear

3.The prerequisites list provides a prerequisite for obtaining the adjacency of course schedule diagram to reduce the time complexity of the algorithm

Entry table (Breadth first traversal)
Statistics the entry degree of each node in the curriculum schedule diagram is generated to generate the entry degree table indegrees
With a queue queue, all nodes with an entry degree of 0 are queued
When the queue is not empty, the first node in the queue will be queued in turn, and this node pre will be deleted in the course schedule diagram
This node pre is not really deleted from the adjacent list, but corresponds to the entry degree -1 of all the neighboring nodes
indegrees[cur] -= 1
When the entry degree of cur at the adjacent node is 0 after the entry degree of -1, it indicates that all precursor nodes of cur have been deleted, so the cur is joined in the team at this time
Execute numCourses–1 each time pre exits the queue
The whole course arrangement diagram is a directed acyclic graph (that is, it can be arranged), then all nodes must join and leave the queue, that is, complete the topological sorting. To put it another way, if there is a ring in the course arrangement diagram, there must be nodes with an entry degree not equal to 0 at all
Therefore, the topology sorts out the number of queues equal to the number of courses, and returns numCourses == 0 to determine whether the courses can be successfully arranged

Code
golang

func canFinish(numCourses int, prerequisites [][]int) bool {
	if numCourses <= 0 {
		return true
	}
	if len(prerequisites) == 0 || len(prerequisites[0]) == 0 {
		return true
	}

	var
	(
		queue  = make([]int, 0)
		edges  = make([][]int, numCourses) // The corresponding edge of the graph
		preCnt = make(map[int]int)         // 前置节点数
	)

	for _, p := range prerequisites { // Build the graph to find the next node list for all nodes
		edges[p[1]] = append(edges[p[1]], p[0])
		preCnt[p[0]] ++ 
		// {0,1} duplicate arrays must not appear in the prerequisites,otherwise it will have to be done again
	}
	for i := 0; i < numCourses; i++ {
		if preCnt[i] == 0 {
			queue = append(queue, i)
		}
	}
	// If the graph has no rings, then all nodes must be in and out of the queue
	// If the graph does not have rings, then all nodes must be queued and queued out. If there are rings, then there are still nodes not traversed when the queue is empty, and then numCourses must not be 0
	for len(queue) != 0 {
		current := queue[0]
		queue = queue[1:] // DeQueue
		numCourses--      // A node was accessed
		for _, v := range edges[current] {
			preCnt[v]--
			if preCnt[v] == 0 {
				queue = append(queue, v)
			}
		}
	}
	return numCourses == 0
}

java

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {//A directed graph of numCourses nodes
        int n=prerequisites.length;//n sides
        ArrayList<Integer> [] adjacencyList=new ArrayList[numCourses];//邻接表
        int [] inDegree=new int[numCourses];//The value of inDegree[i] indicates the degree of entry of node i
        //The adjacency list is first constructed from the set of edges
        for(int i=0;i<numCourses;i++){
            adjacencyList[i]=new ArrayList<>();//The index of the node i is i
        }
        for (int [] pre:prerequisites) {
            adjacencyList[pre[1]].add(pre[0]);//pre=[0,1],node 1 points to node 0
            inDegree[pre[0]]++;
        }
        //Topological sort determines if it is a DAG
        return topologicalSort(adjacencyList,inDegree,numCourses);
    }
    private boolean topologicalSort(ArrayList<Integer> [] adjacencyList,int [] inDegree,int n){
        int res=0;//Topological sort the number of nodes that can be retrieved
        Queue<Integer> queue=new LinkedList<Integer>();//Stores nodes with a degree of 0
        for(int i=0;i<n;i++){
            if(inDegree[i]==0) queue.offer(i);//Node i has an incoming degree of 0 and is added to the queue
        }
         while (!queue.isEmpty()) {
            int i = queue.poll();//fetch node i
            res++;
            for (int child_of_i : adjacencyList[i]) {//For each node that node i points to
                inDegree[child_of_i]--;
                if (inDegree[child_of_i] == 0) queue.offer(child_of_i);
            }
           
        }
        return res==n;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值