1. 程式人生 > 其它 >刷題筆記:並查集(續,LeetCode-959)

刷題筆記:並查集(續,LeetCode-959)

技術標籤:c++leetcode演算法

題目:由斜槓劃分區域

原題連結:https://leetcode-cn.com/problems/regions-cut-by-slashes/

解析

題目需要求解連通塊的個數,我們可以通過並查集進行求解,將聯通的區域合併成同一個集合,最後求解集合的個數。
觀察下圖,我們把單元格分為4個三角形,並進行編號。
對單元格內的合併:

  • 如果是空格‘ ’,我們將(0,1,2,3)進行合併
  • 如果是斜槓‘/’,我們將(0,3),(1,2)進行合併
  • 如果是反斜槓‘\’,我們將(0,1),(2,3)進行合併
    在這裡插入圖片描述

對相鄰單元格的合併,有4種方案:

  • 向右和向下
  • 向右和向上
  • 向左和向下
  • 向左和向上

在這裡,我使用向右和向下合併。

在這裡插入圖片描述

程式碼

class UnionFind {
private:
    int count;
    vector<int> father;
public:
    int getCount(){
        return this->count;
    }
    UnionFind(int n){
        this->count=n;
        father.resize(n);
        for(int i=0;i<n;i++) father[i]=i;
    }
    int find_fa(int x){
        if
(x==father[x]) return x; else { int f=this->find_fa(father[x]); father[x]=f; return f; } } void unino(int a,int b){ int fa=this->find_fa(a); int fb=this->find_fa(b); if(fa!=fb) { father[fa]=fb; this
->count--; } } }; class Solution { public: int regionsBySlashes(vector<string>& grid) { int len=grid.size(); int N=4*len*len; UnionFind uf(N); for(int i=0;i<len;i++){ int r=grid[i].size(); for(int j=0;j<r;j++){ int index=4*(i*len+j); //合併正方形內 if(grid[i][j]=='/'){ //合併(0,3),(1,2) uf.unino(index,index+3); uf.unino(index+1,index+2); }else if(grid[i][j]=='\\'){ //合併(0,1),(2,3) uf.unino(index,index+1); uf.unino(index+2,index+3); }else{ uf.unino(index,index+1); uf.unino(index+1,index+2); uf.unino(index+2,index+3); } //合併區間外,向右,向下 if(j+1<len){ //向右合併 uf.unino(index+1,4*(i*len+j+1)+3); } if(i+1<len){ uf.unino(index+2,4*((i+1)*len+j)); } } } return uf.getCount(); } };