261. Maximum Connected Area
Description
There is a two-dimensional array, only consists of 00 and 11.
You can change a 00 to 11 at most once, please calculate the maximum area of connected 1s1s.
If two 1s1s are adjcent up to down or left to right, they are regrarded connected.
the two-dimensional array has nn rows and mm columns, 1≤n,m≤500.
Have you met this question in a real interview?
Clarification
In example, change any 0 to 1, you can get a connection with an area 3.
Example
Input:
[[0,1]
,[1,0]]
Output:
3
解法1:union-find
思路是将2维降1维。然后先按岛屿最大面积的思路把所有连通块都求出来,每个连通块的root存储其面积。
然后再把matrix里面的所有0节点遍历一遍,上下左右4个方向把所有连通块的面积加起来,再加1。然后求所有的0节点所得到的最大值。
注意:这题不能跟 897. Island City 那样只找下和右2个方向。比如input={{1,0,1,0,1}},第1个0只找右边的话就无法将其跟左边的1结合起来。
代码如下:
class Solution {
public:
/**
* @param matrix: the matrix for calculation.
* @return: return the max area after operation at most once.
*/
int maxArea(vector<vector<int>> &matrix) {
int result = 0;
int m = matrix.size();
int n = matrix[0].size();
father.resize(m * n);
area.resize(m * n);
// initialize
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] != 0) {
father[i * n + j] = i * n + j;
area[i * n + j] = 1;
non_zero_count++;
}
}
}
if (non_zero_count == m * n) {
return non_zero_count;
}
//union-find
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] != 0) {
for (int k = 0; k < 4; ++k) {
int newX = i + dx[k];
int newY = j + dy[k];
if (newX >= 0 && newX < m && newY >= 0 && newY < n && matrix[newX][newY] != 0) {
add(i * n + j, newX * n + newY);
}
}
}
}
}
// go thru the matrix's 0
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == 0) {
int count = 1;
set<int> roots;
for (int k = 0; k < 4; ++k) {
int newX = i + dx[k];
int newY = j + dy[k];
if (newX >= 0 && newX < m && newY >= 0 && newY < n && matrix[newX][newY] != 0) {
int newRoot = find(newX * n + newY);
if (area[newX * n + newY] > 0 && roots.find(newRoot) == roots.end()) {
roots.insert(newRoot);
count += area[newRoot];
}
}
}
result = max(result, count);
}
}
}
return result;
}
private:
vector<int> father;
vector<int> area;
int count = 0;
int non_zero_count = 0;
vector<int> dx = {0, 0, 1, -1};
vector<int> dy = {1, -1, 0, 0};
int find(int x) {
if (father[x] == x) return x;
return father[x] = find(father[x]);
}
void add(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if (root_a != root_b) {
father[root_a] = root_b;
area[root_b] += area[root_a];
}
}
};
解法2:BFS
TBD