举例
求下面矩阵的四连通域
[
1
1
0
0
0
1
0
1
0
0
0
1
1
0
0
0
0
0
1
0
0
0
0
0
1
]
(3)
\left[ \begin{matrix} 1 & 1 & 0 & 0 & 0 \\ 1 & 0 & 1 & 0 & 0 \\ 0 & 1 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1\\ \end{matrix} \right] \tag{3}
⎣⎢⎢⎢⎢⎡1100010100011000001000001⎦⎥⎥⎥⎥⎤(3)
结果
结果应该是有4个四连通域,分别是
左上角的三个1, 稍靠右的三个1. 右下角的两个1,总共四个四连通域。
如何使用c++代码得到结果
可以使用BFS广度优先遍历得到结果
思路
- 先访问左上角的1,发现其可以被加入连通域,
- 然后访问该元素的四邻域,如果有1的话,就加入到相同的连通域中
- 对目前连通域的其他元素进行相似的操作
实际代码实现
通常BFS都用 queue来实现,leetcode上有很多这样的题目。代码框架是:
vector<int> tmp; //结果
vector<int> mask // 用于不再访问之前访问过的元素
queue<int> q; //用于存储当前的连通域
q.push(...); //将第一个合适的解压入
while(! q.empty())
{
int t = q.front();
q.pop();
if(t == 你想要的结果)
{
tmp.push_back(...)
mask[... ] = true;
}
if( mask[ i+1] == false) //保证访问的元素之前没有访问过,如果合适,就加入到队列中
q.push(...)
}
另外一种框架是 : (我觉得这种框架更好,其会在访问某一层后记录step,这就是好处)
void BFS(Node start, Node target)
{
queue<int> q;
set<int> visited;
q.push(start);
visited.insert(start);
int step = 0;
while (q not empty) {
int sz = q.size();
// 处理这一整层的node
for (int i = 0; i < sz; i++) {
int qnode = q.front();
q.pop();
if (qnode == target) {
return target;
}
for (int adj : qnode.adj()) {
if (adj is not visited) {
q.push(adj);
visited.insert(adj);
}
}
}
step++;
}
}
完整代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Point
{
int r;
int c;
Point(int r_, int c_) : r(r_), c(c_){}
Point(const Point& p) : r(p.r), c(p.c){}
};
class Solution
{
public:
int m;
int n;
//判断索引点不要越界,该点之前没有访问过,该点是有效的点
bool isvalid(int i, int j, vector<vector<int>>& matrix, vector<vector<bool>>& mask)
{
return i>=0 && i<m && j>=0 && j<n && !mask[i][j] && matrix[i][j]==1;
}
//将合适的点加入到队列中,并标记其被访问过
void add(int i, int j, vector<vector<int>>& matrix, queue<Point>& q, vector<vector<bool>>& mask)
{
if(isvalid(i, j, matrix, mask))
{
q.push(Point(i,j));
mask[i][j]=true;
}
}
//主代码,两重for循环+一个queue
vector<vector<Point>> bwlabel(vector<vector<int>> &matrix)
{
m=matrix.size();
n=matrix[0].size();
vector<vector<Point>> res;
vector<Point> tmp;
vector<vector<bool>> mask(m, vector<bool>(n,false));
for(int i=0; i<m;i++)
{
for(int j=0; j<n; j++)
{
if(mask[i][j] || matrix[i][j] == 0)
continue;
tmp.clear();
queue<Point> q;
q.push(Point(i,j));
mask[i][j] = true;
while(!q.empty())
{
Point t = q.front();
q.pop();
tmp.push_back(t);
//根据四邻域定义得来
add(t.r-1, t.c, matrix, q, mask);
add(t.r+1, t.c, matrix, q, mask);
add(t.r, t.c-1, matrix, q, mask);
add(t.r, t.c+1, matrix, q, mask);
}
res.push_back(tmp);
}
}
return res;
}
};
int main()
{
vector<vector<int>> m = {
{1,1,0,0,0},
{1,0,1,0,0},
{0,1,1,0,0},
{0,0,0,1,0},
{0,0,0,0,1},
{0,0,0,0,0}
};
vector<vector<int>> n = {{}};
Solution s;
vector<vector<Point>> res = s.bwlabel(m);
vector<vector<Point>> rss = s.bwlabel(n);
return 0;
}