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);
                        }
    
                    }
                }    
        }
    };
  • 相关阅读:
    C++输入输出缓冲区的刷新问题
    C++11中新特性之:initializer_list详解
    GCC --verbose选项, -lpthread 和-pthread的区别
    C语言的可变参数
    YCM的安装与配置
    【机器学习】正则化的线性回归 —— 岭回归与Lasso回归
    一文读懂线性回归、岭回归和Lasso回归
    美团酒旅数据治理实践
    kettle完成一个数据库到另一个数据的整体迁移
    kettle完成一个数据库到另一个数据的整体迁移
  • 原文地址:https://www.cnblogs.com/zzw-/p/13362836.html
Copyright © 2011-2022 走看看