1. 程式人生 > 其它 >力扣(leetcode)#959 由斜槓劃分區域(#3)

力扣(leetcode)#959 由斜槓劃分區域(#3)

技術標籤:leetcode練習leetcodec++演算法圖論

題目

原題連結:力扣(LeetCode)#1319

解析

依然是並查集維護連通分量的問題,本題主要難點在於如何劃分連通分量。


將每一個1*1的小方格都按照這個模式進行劃分:

  1. 如果grid[i][j]=‘\\’,那麼是1和2進行合併,0和3進行合併
  2. 如果grid[i][j]=‘/’,那麼是0和1進行合併,2和3進行合併
  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--; } } };

結果

在這裡插入圖片描述