日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2020.12.15

發布時間:2025/4/16 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020.12.15 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2020.12.15

1.有向圖判斷是否有環

對于圖類問題,首先利用鄰接表對圖進行表示,如圖所示:通常使用List<List>的格式存儲表示。

在本題中,輸入為[a,b]表示b指向a,所以鄰接表生成代碼為:

List<List<Integer>> edges = new ArrayList<List<Integer>>(); for (int i = 0; i < numCourses; ++i) { // numCourses為節點個數edges.add(new ArrayList<Integer>()); } for (int[] info : prerequisites) {edges.get(info[1]).add(info[0]); }

思路一:拓撲排序(bfs)

通過拓撲排序生成的節點序列,可以確定是否存在環。

構建的鄰接表就是我們通常認識的鄰接表,每一個結點存放的是后繼結點的集合。

該方法的每一步總是輸出當前無前趨(即入度為零)的頂點。為避免每次選入度為 0 的頂點時掃描整個存儲空間,可設置一個隊列暫存所有入度為0的頂點。

具體做法如下:

1、在開始排序前,統計課程安排圖中每個節點的入度,生成 入度表 ,將入度為 0 的頂點均入隊列。

2、只要隊列非空,就從隊首取出入度為 0 的頂點,將這個頂點pre輸出到結果集(在生成拓撲排序)中,并且將這個頂點的所有鄰接點cur的入度減 1,在減 1 以后,發現這個鄰接點的入度為 0 ,就繼續入隊。

最后檢查結果集中的頂點個數是否和課程數相同即可。

class Solution {public boolean canFinish(int numCourses, int[][] prerequisites) {int[] indegrees = new int[numCourses];List<List<Integer>> edges = new ArrayList<>();Queue<Integer> queue = new LinkedList<>();int valid = 0;for(int i = 0; i < numCourses; i++)edges.add(new ArrayList<>());// Get the indegree and adjacency of every course.for(int[] info : prerequisites) {indegrees[info[0]]++;edges.get(info[1]).add(info[0]);}// Get all the courses with the indegree of 0.for(int i = 0; i < numCourses; i++)if(indegrees[i] == 0) queue.add(i);// BFS TopSort.while(!queue.isEmpty()) {int pre = queue.poll();valid++;for(int cur : edges.get(pre))if(--indegrees[cur] == 0) queue.add(cur);}return numCourses == valid;} }

思路二:dfs

class Solution {List<List<Integer>> edges;public boolean canFinish(int numCourses, int[][] prerequisites) {edges = new ArrayList<>();boolean[] visited = new boolean[numCourses];boolean[] stack = new boolean[numCourses];for(int i = 0; i < numCourses; i++)edges.add(new ArrayList<>());for(int[] info : prerequisites) {edges.get(info[1]).add(info[0]);}for (int i=0;i<numCourses;i++) {if (!visited[i]) {if (dfs(visited,stack,i))return false;}}return true;}public boolean dfs(boolean[] visited, boolean[] stack, int i) {visited[i] = true;stack[i] = true;for (int index : edges.get(i)) {if (visited[index] && stack[index]) return true;if (visited[index]) continue;if (dfs(visited, stack, index)) return true;}stack[i] = false;return false;} }

2.判斷無向圖是否有環

思路一:并查集

/*** *利用并查集判斷無向圖中是否有環*/ public class Solution {public int[] parent;//記錄并查集元素父節點public int depth[];//記錄并查集每個元素的深度//初始化操作public Solution(int nums) {this.parent = new int[nums];this.depth = new int[nums];for(int i = 0;i<nums;i++) {parent[i] = -1;}}public int find_root(int x) {//查找x的代表元素int root = x;while(parent[root]!=-1) {root = parent[root];}return root;}public boolean union(int x,int y) {int x_root = find_root(x);int y_root = find_root(y);if(x_root == y_root) {return false;//說明有環}else {if(depth[x_root]>depth[y_root]) {//如果x_root樹更深,則把y_root加到x_root上parent[y_root] = x_root;}else if(depth[x_root]<depth[y_root]) {//如果y_root樹更深,則把x_root加到y_root上parent[x_root] = y_root;}else if(depth[x_root] == depth[y_root]) {//相等的情況下,加到哪個都行,相應的數深+1parent[x_root] = y_root;depth[x_root]++;}}return true;}public static void main(String[] args) {int[][] rec = {//鄰接矩陣{0,1,0,0,0},{1,0,1,0,1},{0,1,0,1,0},{0,0,1,0,0},{0,1,0,0,0}};Solution s = new Solution(5);for(int i = 0;i<rec.length;i++) {for(int j = 0;j<i;j++) {if(rec[i][j] == 1) {boolean b = s.union(i, j);if(b == false ) {System.out.println("有環");return;}}}}System.out.println("沒有環");} }

總結

以上是生活随笔為你收集整理的2020.12.15的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。