1. 程式人生 > >LeetCode207——課程表

LeetCode207——課程表

我的LeetCode程式碼倉:https://github.com/617076674/LeetCode

原題連結:https://leetcode-cn.com/problems/course-schedule/description/

題目描述:

知識點:拓撲排序

思路:拓撲排序

拓撲排序的演算法步驟如下:

(1)定義一個佇列Q,並把所有入度為0的節點加入佇列。

(2)取隊首節點,輸出。然後刪去所有從它出發的邊,並令這些邊到達的頂點的入度減1,如果某個頂點的入度減為0,則將其加入佇列。

(3)反覆進行(2)操作,直到佇列為空。如果佇列為空時入過隊的節點數恰好為N,說明拓撲排序成功,圖G為有向無環圖;否則,拓撲排序失敗,圖G中有環。

時間複雜度和空間複雜度均是O(n)。

JAVA程式碼:

public class Solution {

    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] inDegree = new int[numCourses];
        int[][] graph = new int[numCourses][numCourses];
        for(int i = 0; i < prerequisites.length; i++){
            graph[prerequisites[i][1]][prerequisites[i][0]] = 1;
            inDegree[prerequisites[i][0]]++;
        }
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] == 0){
                queue.add(i);
            }
        }
        int num = 0;
        while(!queue.isEmpty()){
            int u = queue.poll();
            for(int v = 0; v < numCourses; v++){
                if(graph[u][v] != 0){
                    inDegree[v]--;
                    if(inDegree[v] == 0){
                        queue.add(v);
                    }
                }
            }
            num++;
        }
        return num == numCourses;
    }
}

JAVA解題報告:

C++程式碼:

class Solution {
	public:
		bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
			int inDegree[numCourses] = {0};	//記錄每個節點的入度
			vector<int> graph[numCourses];
			for(int i = 0; i < prerequisites.size(); i++) {
				graph[prerequisites[i].second].push_back(prerequisites[i].first);
				inDegree[prerequisites[i].first]++;
			}
			int num = 0;	//記錄加入拓撲序列的頂點數
			queue<int> q;
			for(int i = 0; i < numCourses; i++) {
				if(inDegree[i] == 0) {
					q.push(i);	//將所有入度為0的頂點入隊
				}
			}
			while(!q.empty()) {
				int u = q.front();	//取隊首頂點u
				q.pop();
				for(int i = 0; i < graph[u].size(); i++) {
					int v = graph[u][i];	//u的後繼節點v
					inDegree[v]--;	//頂點v的入度減1
					if(inDegree[v] == 0) {
						q.push(v);	//頂點v的入度減為0則入隊
					}
				}
//				graph[u].clear(); 
				num++;
			}
			if(num == numCourses){
				return true;	//加入拓撲序列的頂點數為numCourses,說明拓撲排序成功 
			}
			return false;	//加入拓撲序列的頂點數小於numCourses,說明拓撲排序失敗 
		}
};

C++解題報告: