力扣(leetcode)#959 由斜槓劃分區域(#3)
阿新 • • 發佈:2021-01-27
技術標籤:leetcode練習leetcodec++演算法圖論
題目
原題連結:力扣(LeetCode)#1319
解析
依然是並查集維護連通分量的問題,本題主要難點在於如何劃分連通分量。
將每一個1*1的小方格都按照這個模式進行劃分:
- 如果grid[i][j]=‘\\’,那麼是1和2進行合併,0和3進行合併
- 如果grid[i][j]=‘/’,那麼是0和1進行合併,2和3進行合併
- 如果grid[i][j]=‘ ’,那麼是0,1,2,3合併
上面是三種內部合併的情況討論。
接下來討論小方格之間的合併問題:
- 對於2號區域可以和右邊一個小方格的0號區域進行合併
- 對於3號區域可以和下邊一個小方格的1號區域進行合併
到此,分析結束,將並查集的模板寫完之後,根據上述分析過程進行合併即可。
程式碼
class Solution {
private:
int cnt;
vector<int> a;
public:
int regionsBySlashes(vector<string>& grid) {
int n=grid.size();
cnt=4*n*n;
init(cnt);
for(int i=0;i<n;i++)
{
for(int j= 0;j<n;j++)
{
if(grid[i][j]=='/')
{
merge(a[4*n*i+4*j],a[4*n*i+4*j+1]);
merge(a[4*n*i+4*j+2],a[4*n*i+4*j+3]);
}
else if(grid[i][j]=='\\'){
merge(a[4*n*i+4*j],a[4*n* i+4*j+3]);
merge(a[4*n*i+4*j+1],a[4*n*i+4*j+2]);
}
else{
merge(a[4*n*i+4*j],a[4*n*i+4*j+3]);
merge(a[4*n*i+4*j+1],a[4*n*i+4*j+2]);
merge(a[4*n*i+4*j],a[4*n*i+4*j+1]);
}
if(j<n-1)
{
merge(a[4*n*i+4*j+2],a[4*n*i+4*(j+1)]);
}
if(i<n-1)
merge(a[4*n*i+4*j+3],a[4*n*(i+1)+4*j+1]);
}
}
return cnt;
}
void init(int n)
{
for(int i=0;i<n;i++)
a.push_back(i);
}
int find(int var)
{
if(var==a[var])
return var;
else
return a[var]=find(a[var]);
}
void merge(int x, int y)
{
int a1=find(x);
int a2=find(y);
if(a1!=a2)
{
a[a1]=a2;
cnt--;
}
}
};