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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Depth-first Search深度优先搜索专题3

發(fā)布時(shí)間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Depth-first Search深度优先搜索专题3 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

473. Matchsticks to Square

思路:有n根長度不一的火柴,這些火柴可以拼接在一起,但不能被折斷。這些火柴能夠圍城一個(gè)正方形嗎?每個(gè)火柴可以并且必須使用一次。分析得到每個(gè)邊的長度應(yīng)該是所有火柴長度和的1/4。接下來就是將火柴分組。可以用4個(gè)變量或者一個(gè)數(shù)組記錄每組火柴目前已經(jīng)分配的長度。如果正好分配完成就返回true,否則返回false。
這里的一個(gè)小技巧是對輸入nums排序。先分配火柴長度長的火柴。這樣可以更早地找到不合理分配的情況。
代碼

743. Network Delay Time

思路:這是一道關(guān)于在圖中找從一個(gè)頂點(diǎn)到其他頂點(diǎn)的最短路徑的問題。我的錯(cuò)誤在于忽略了最短路徑
思路1:普通的dfs。只是要注意遍歷的時(shí)候先訪問距離短的邊。
思路2:Dijkstra’s Algorithm。但是我比較了dfs版本的代碼與堆實(shí)現(xiàn)版本的代碼,認(rèn)為思路是一樣的。只是代碼書寫結(jié)構(gòu)不同。排序位置不同。它們的耗時(shí)確實(shí)不同。前者耗時(shí)101ms,后者耗時(shí)51ms。

public int networkDelayTime(int[][] times, int N, int K) {int[] costs = new int[N+1];Arrays.fill(costs,-1);Map<Integer, List<int[]>> map = new HashMap<Integer, List<int[]>>();for(int[] a : times){if( map.get(a[0])==null){map.put(a[0],new ArrayList<int[]>());}map.get(a[0]).add(new int[]{a[1],a[2]});}//按dist排序,可以優(yōu)先選擇距離短的邊for (int node: map.keySet()) {//(a, b) -> a[0] - b[0]Collections.sort(map.get(node), new Comparator<int[]>(){public int compare(int[] o1, int[] o2) {return o1[1]-o2[1];}});}visitNode(map,costs,K,0);int max = 0;for(int i=1;i<=N;i++){if(costs[i] == -1) return -1;max = Math.max(max, costs[i]);}return max;}public void visitNode(Map<Integer,List<int[]>> timeMap,int[] costs,int node,int cost){if(costs[node]!=-1){if(cost >= costs[node]){return;}}costs[node] = cost;if(timeMap.get(node)!=null){for(int[] edge :timeMap.get(node)){visitNode(timeMap,costs,edge[0],edge[1]+cost);}}} public int networkDelayTimeV2(int[][] times, int N, int k) {Map<Integer, List<int[]>> graph = new HashMap<Integer, List<int[]>>();for(int[] a : times){if( graph.get(a[0])==null){graph.put(a[0],new ArrayList<int[]>());}graph.get(a[0]).add(new int[]{a[1],a[2]});}PriorityQueue<int[]> heap = new PriorityQueue<int[]>(N,new Comparator<int[]>(){public int compare(int[] o1, int[] o2) {return o1[1]-o2[1];}});heap.offer(new int[]{k,0});int[] dist = new int[N+1];Arrays.fill(dist,Integer.MAX_VALUE);while(!heap.isEmpty()){int[] info = heap.poll();int d = info[1];int node = info[0];if(dist[node]!=Integer.MAX_VALUE) continue;dist[node] = d;if(graph.containsKey(node)){for(int[] edge :graph.get(node)){if(dist[edge[0]]==Integer.MAX_VALUE){heap.offer(new int[]{edge[0],edge[1]+d});}}}}int max = 0;for(int i=1;i<=N;i++){if(dist[i] == Integer.MAX_VALUE) return -1;max = Math.max(max, dist[i]);}return max;}

思路3:也是Dijkstra’s算法。但是是用數(shù)組實(shí)現(xiàn)的。快很多,耗時(shí)13ms。代碼
代碼

417. Pacific Atlantic Water Flow

思路:這道題目不難。難的是理解題目含義。紅色框的所有位置相當(dāng)于都是Pacific的入口。能到達(dá)這些位置的點(diǎn),都能流入Pacific。同理對于Atlantic也一樣。標(biāo)記哪些位置是能流入二者的點(diǎn)就是需要返回的點(diǎn)。

代碼

207. Course Schedule

思路:檢測有向圖上是否有環(huán)。
思路1:BFS。1、構(gòu)建圖;2 找到入度為0的點(diǎn),加入到隊(duì)列;3 從隊(duì)列中彈出一個(gè)元素,count+1,找到這個(gè)元素可以達(dá)到的點(diǎn)(課程),將這些課程的入度減1;4 如果發(fā)現(xiàn)有新的入度為0的點(diǎn),繼續(xù)加入到隊(duì)列;5 重復(fù)步驟3,4直到隊(duì)列為空;6 判斷count是否等于課程數(shù)。如果等于返回true。
思路2:DFS。1、構(gòu)建圖;2 參考802. Find Eventual Safe States,我們設(shè)計(jì)節(jié)點(diǎn)的訪問有三種狀態(tài),還沒有開始訪問節(jié)點(diǎn)是白(0),開始訪問一個(gè)節(jié)點(diǎn)是灰(1),訪問一個(gè)節(jié)點(diǎn)結(jié)束是黑(2);3 我們依次訪問所有課程,如果節(jié)點(diǎn)狀態(tài)是1,則表示有環(huán),返回false;如果節(jié)點(diǎn)狀態(tài)是2,則表示已經(jīng)訪問成功直接返回true;如果節(jié)點(diǎn)狀態(tài)是0,則進(jìn)入訪問,狀態(tài)修改為1;接著dfs訪問這個(gè)節(jié)點(diǎn)的鄰接節(jié)點(diǎn)。
代碼

721. Accounts Merge

思路:這題目初看上去很簡單。map吧。把email和用戶名做映射。但實(shí)際上沒這么簡單。
學(xué)習(xí):DFS。這是一個(gè)圖。圖的鏈接技巧是將第一個(gè)email和同一個(gè)list內(nèi)的其他email雙向相連。連通的email就是在同一個(gè)組內(nèi)。
DFS思路代碼 AccountsMergeV2
union-find代碼思路 AccountsMergeV3 AccountsMergeV4
我自己寫的union-find超時(shí)了。

542. 01 Matrix

思路:這道題目DFS思路可以解決。但有一個(gè)細(xì)節(jié)需要解決。如果matrix[i][j]=1,計(jì)算最近0距離的時(shí)候。1 先判斷周圍是否有0,如果有則距離為1,直接退出。2 不滿足條件1,繼續(xù)搜索周圍相鄰節(jié)點(diǎn)。這個(gè)過程中,沒有把相鄰節(jié)點(diǎn)的計(jì)算保留下來,所以會(huì)有重復(fù)計(jì)算.在整個(gè)dfs過程中并沒有對r的有效修改,所以會(huì)有重復(fù)的。 例如,在計(jì)算(0,4)的最近0距離的時(shí)候,會(huì)計(jì)算(1,4)點(diǎn)的最近0距離,但是結(jié)果并沒有保存下來。
這個(gè)問題的解決,在別人文章中學(xué)到了。在從左到右,從上到下的遍歷中,dist[i][j] = Min(dist[i][j],min(dist[i-1][j]+1,dist[i][j-1]+1))。因?yàn)樵谶@樣的遍歷中,(i-1,j)和(i,j-1)節(jié)點(diǎn)是計(jì)算過的。在從下到上,從右到左的遍歷中,dist[i][j] = Min(dist[i][j],min(dist[i+1][j]+1,dist[i][j+1]+1))。因?yàn)樵谶@樣的遍歷中,(i,j+1)和(i+1,j)節(jié)點(diǎn)是計(jì)算過的。
這是一種DP的思想。但是這樣的思維,就確定整個(gè)計(jì)算過程不會(huì)出錯(cuò)。要不,我總會(huì)想,是應(yīng)該先計(jì)算(1,4)還是先計(jì)算(0,4)。究竟是(0,4)點(diǎn)的距離影響(1,4)還是(1,4)點(diǎn)的距離影響(0,4)。而這種從上到下,從左到右遍歷一次;從下到上,從右到左再遍歷一次,就好多了。
學(xué)習(xí):BFS思路,考慮從matrix[i][j]=0的點(diǎn)開始擴(kuò)散查找,更有意思了。
代碼

總結(jié)

以上是生活随笔為你收集整理的Depth-first Search深度优先搜索专题3的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。