凉了,so sad.
十月份一直在整论文的事儿,工作方面的东西没看,题也没做,结果就是碰到手撕代码就挂QAQ
也许碰到以前做过的类型题思路会好点,但是这个题也没做过,就硬想,结果只想出了漏洞百出的思路。
题目如下:
问题描述:
给定一个M*N的矩阵,里面有数字1,0。 + 然后给定一个坐标:(x, y)。
请写一个程序计算与坐标x, y值相同,且连通的数字个数。
“连通” 定义为:左右或者上下数值一样则认为这两个块是连通的,连通具有传递性。
输入:matrix, x, y
输出:n
举例:
输入:
matrix = [
[1, 0, 1, 0]
[1, 0, 0, 0]
[1, 1, 0, 1]
[0, 1, 0, 1]
[1, 1, 0, 0]
}
我当时想到的思路就是去判断目标点(x,y)周围的十字方向的四个点是否连通,如果连通则继续递归判断。
当时手撕没撕出来(写的什么稀烂代码),就直接给面试官讲了思路,面试官听完回了一句,有个条件你没提到。
然后我当时就懵了,没想到自己已经那么菜了。
结束之后我百度了才发现,如果按照我的简单思路来写的话,是很容易重复遍历的,比如目标点的左侧,上侧,以及左上侧三个点都和目标点连通的话,那么就出现了无限递归死循环的情况。所以必须再利用一个mask来统计已遍历过的点,避免出现重复遍历导致死循环的出现。
以下内容和代码主要参考这篇博客。
这样的无向图遍历问题主要采用BFS广度优先搜索实现。主要思路为:
- 先访问目标点的值,并进入队列。
- 然后访问该元素的四邻域,如果是连通的话,就进入到队列中。
- 取出队列中的点,继续上一步操作,直至遍历完成。
实际代码实现采用队列居多,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(...)
}
根据题目要求重新写了代码。
完整代码为:
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
// 判断该点是否已被遍历过或是坐标越界
bool check(vector<vector<int>>& matrix, vector<vector<bool>>& mask, int x, int y, int value) {
return x >= 0 && y >= 0 && x < matrix.size() && y < matrix[0].size() && matrix[x][y] == value && mask[x][y] != true;
}
// 如果该点未越界且未被遍历过,则统计加1,将其加入队列继续检索
void add(vector<vector<int>>& matrix, vector<vector<bool>>& mask, queue<pair<int, int>>& q, int x, int y, int value, int& result) {
if (check(matrix, mask, x, y, value)) {
result += 1;
q.push(pair<int, int>{x, y});
mask[x][y] = true;
}
}
int main() {
vector<vector<int>> matrix{ {1, 0, 1, 0},{1, 0, 0, 0},{1, 1, 0, 1},{0, 1, 0, 1},{1, 1, 0, 0} };
vector<vector<bool>> mask(matrix.size(), vector<bool>(matrix[0].size(), false));
queue <pair<int, int>> q;
int result = 1;
int x = 2;
int y = 2;
int value = matrix[x][y];
cout << value << endl;
pair<int, int> temp;
mask[x][y] = true;
q.push(pair<int, int>{x, y});
while (!q.empty()) {
temp = q.front();
q.pop();
add(matrix, mask, q, temp.first, temp.second + 1, value, result);
add(matrix, mask, q, temp.first, temp.second - 1, value, result);
add(matrix, mask, q, temp.first - 1, temp.second, value, result);
add(matrix, mask, q, temp.first + 1, temp.second, value, result);
}
cout << result << endl;
return 0;
}