zoukankan      html  css  js  c++  java
  • 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);
                        }
    
                    }
                }    
        }
    };
  • 相关阅读:
    经典问题的非经典解法
    经典问题之树的深度
    35、AndroidView的滑动方式
    30、Android属性动画
    31、Android矢量动画
    36、AndroidCanvas画布
    27、AndroidEventBus
    28、AndroidRxjava
    32、Android事件分发机制
    29、Android基本动画
  • 原文地址:https://www.cnblogs.com/zzw-/p/13362836.html
Copyright © 2011-2022 走看看