https://leetcode-cn.com/problems/making-a-large-island/
在二维地图上, 0
代表海洋, 1
代表陆地,我们最多只能将一格 0
海洋变成 1
变成陆地。
进行填海之后,地图上最大的岛屿面积是多少?(上、下、左、右四个方向相连的 1
可形成岛屿)
示例 1:
输入: [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。
示例 2:
输入: [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。
示例 3:
输入: [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。
说明:
1 <= grid.length = grid[0].length <= 50
0 <= grid[i][j] <= 1
思路 穷举这个变化的点+并查集
class Solution {
public:
vector<int> iRank;
vector<int> nums;
int xx[4]= {0,0,-1,1};
int yy[4]= {-1,1,0,0};
int n,m;
int largestIsland(vector<vector<int>>& grid) {
vector<int> parent;
n=grid.size();
m=grid[0].size();
parent.resize(n*m);
iRank.resize(n*m);
nums.resize(n*m);
for(int i=0; i<m*n; i++) {
parent[i]=-1;
if(grid[i/m][i%m])
parent[i]=i;
iRank[i]=5;
}
for(int i=0; i<n; i++)
for(int j=1; j<m; j++) {
if(grid[i][j]&&grid[i][j-1])
uni(i*m+j,i*m+j-1,parent);
}
for(int i=0; i<m; i++)
for(int j=1; j<n; j++) {
if(grid[j][i]&&grid[j-1][i])
uni(j*m+i,m*(j-1)+i,parent);
}
int imax=getnums(parent);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++) {
if(grid[i][j]==0) {
vector<int> paa(parent);
tian(i,j,paa,grid);
imax=max(imax,getnums(paa));
}
}
//cout<<imax<<endl;
return imax;
}
void tian(int i,int j,vector<int> & pa,vector<vector<int>>& grid) {
pa[i*m+j]=i*m+j;
for(int k=0; k<4; k++) {
int nx=i+xx[k];
int ny=j+yy[k];
if(nx<0||nx>=n||ny<0||ny>=m)
continue;
else {
if(grid[nx][ny])
uni(i*m+j,nx*m+ny,pa);
}
}
}
int root(int p,vector<int> &pa) {
if(p != pa[p]) {
pa[p] = root(pa[p],pa);
}
return pa[p];
}
void uni(int p, int q,vector<int> &pa) {
int proot = root(p,pa);
int qroot = root(q,pa);
if(proot == qroot) return ;
if(iRank[proot] > iRank[qroot]) {
pa[qroot] = proot;
} else {
if(iRank[proot] = iRank[qroot]) {
iRank[qroot]++;
}
pa[proot] = qroot;
}
}
int getnums(vector<int> p) {
for(int i=0; i<p.size(); i++)
nums[i]=0;
for(int i=0; i<p.size(); i++) {
if(p[i]>=0)
nums[root(i,p)]++;
}
return *max_element(nums.begin(),nums.end());
}
};