1. 程式人生 > 實用技巧 >LeetCode 547 朋友圈

LeetCode 547 朋友圈

題目描述連結:https://leetcode-cn.com/problems/friend-circles/

解題思路:基本思想採用DFS的方法進行深搜。用一個訪問來記錄每個節點是否被訪問,從頭節點開始深度優先搜尋朋友。每進行以此搜尋,就會把開始節點所屬的朋友圈全部人員標記完成。

然後再主函式找到未被搜尋的節點,繼續深搜即可。記錄主函式呼叫深搜函式的次數就是朋友圈的個數。

另外記錄一下自己在解這道題過程中犯過的錯誤。開始時候自己以為這是上三角矩陣,那麼直接對上三角矩陣進行搜尋就好了,結果就是出現了錯誤答案,通過分析總結原因如下:

這裡用例子來說明:如有一個四階矩陣,表示朋友關係分別為[0,3],[1,2],[2,3],如果用上三角矩陣的話,第一次搜尋會將0,3標記,但由於是上三角則對3的朋友進行搜尋時不會再搜到2了(3>2,在矩陣的第四行搜尋只能從第四列開始,而第四列後面沒有元素,則表示第三行搜尋結束)。導致再從1開始搜尋,將[1,2],和[2,3]搜尋到,最終答案為2而不是應該的正確答案1。

所以每次遞迴搜尋的時候都應該從行的第一個元素開始搜尋。但修改之後出現了棧溢位的問題,即遞迴無法退出了,一直搜下去了。分析原因為:由於是對稱矩陣會陷入死遞迴(即無窮的遞迴自身的呼叫),比如:如果M[0][3]=1,接下來我們就會對M[3]這一行進行搜尋而M[3][0]=M[0][3]=1,就會再對0行進行搜尋,0行又會到3行進行搜尋,這樣遞迴就無法退出了。解決方法就是再對其進行搜尋之前判斷其是否已經被標記,如果已經被標記過了,說明改節點的朋友已經全部找到了,沒有必要對改節點列號對應的行進行搜尋了:

採用DFS實現的LeetCode程式碼如下:

class Solution {
public:
    
bool vis[205]; int ans; int findCircleNum(vector<vector<int>>& M) { int len=M[0].size(); for(int i=0;i<len;++i){ if(!vis[i]){ dfs(i,M); ans++; } } return ans; } void dfs(int start,vector<vector<int
>> M){ if(start==M[start].size()){ return ; } int j; for(j=0;j<M[start].size();j++){ if(M[start][j]==1){ if(vis[j]!=1){ vis[j]=1; dfs(j,M); } } } } };