leetcode 200岛屿的个数
主要考察图搜索:
方法一:染色法,时间O(mn)
遍历一遍,再通过BFS或DFS将所有临近岛屿染色,使用dfs时将numIslands中的bfs换成dfs即可;
/***** 遍历所有的点: 只要遇见陆地(1),投放1枚原子弹,爆炸冲击波以BFS或DFS的形式向外扩散,使得自身及所有相邻区域全部夷为平地; 最终遍历结束,原子弹使用数目即为岛屿次数 *****/ class Solution { public: vector<vector<int> > dirs={{-1,0},{0,1},{1,0},{0,-1}}; int numIslands(vector<vector<char>>& grid) { int m=grid.size(); if(m==0) return 0; int n=grid[0].size(); if(n==0) return 0; int res=0; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(grid[i][j]=='1'){ res++;bfs(grid,i,j); } } } return res; } void dfs(vector<vector<char>>&grid,int i,int j){ int m=grid.size(),n=grid[0].size(); if(i<0 || i>=m ||j<0 ||j>=n||grid[i][j]!='1') return; grid[i][j]='0'; for(auto dir:dirs){ dfs(grid,i+dir[0],j+dir[1]); } } void bfs(vector<vector<char>>&grid,int i,int j){ int m=grid.size(),n=grid[0].size(); queue<pair<int,int>> q; pair<int,int> p; p.first=i,p.second=j; q.push(p); while(!q.empty()){ p=q.front(); q.pop(); int a=p.first,b=p.second; if(a>=0 && a<m && b>=0 && b<n && grid[a][b]=='1'){ grid[a][b]='0'; for(auto dir:dirs){ pair<int,int> tmp; tmp.first=a+dir[0],tmp.second=b+dir[1]; q.push(tmp); } } } } };
第二种:并查集的方法,
class Solution { public: int findCircleNum(vector<vector<int>>& M) { if (M.empty()) return 0; int n = M.size(); vector<int> leads(n, 0); for (int i = 0; i < n; i++) { leads[i] = i; } // initialize leads for every kid as themselves int groups = n; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { // avoid recalculate M[i][j], M[j][i] if (M[i][j]) { int lead1 = find(i, leads); int lead2 = find(j, leads); if (lead1 != lead2) { // if 2 group belongs 2 different leads, merge 2 group to 1 leads[lead1] = lead2; groups--; } } } } return groups; } private: int find(int x, vector<int>& parents) { return parents[x] == x ? x : find(parents[x], parents); } };