关于并查集和漫水法

漫水法今天第一次遇到,感觉非常新鲜,漫水法可以视为简单版本的并查集。两者的异同点可以从leedcode200这道题目来分析:
leetcode200:Number of Islands
题意:给一个二维矩阵,其中1代表陆地,0代表水域,相连的陆地称为岛屿,判断有多少个岛屿
并查集解法:

class union_find{
public:
    union_find(vector> nums){
        num = 0;
        for(int i = 0;i < nums.size();++i){
            for(int j = 0;j < nums[0].size();++j){
                if(nums[i][j] == '1'){
                    num ++;
                }
                id.push_back(i*nums[0].size()+j);
            }
        }
    }
    int find(int x){
        while(x != id[x]){
            id[x] = id[id[x]];
            x = id[x];
        }
        return x;
    }
    void unit(int x,int y){
        x = find(x);
        y = find(y);
        if(x == y)return;
        num--;
        id[x] = y;
    }
    int island_num(){
        return num;
    }
private:
    vector id;
    int num;
};
class Solution {
public:
    int numIslands(vector>& grid) {
        if(grid.size() == 0 || grid[0].size() == 0){
            return 0;
        }
        int n = grid[0].size();
        union_find uf(grid);
        for(int i = 0;i < grid.size();i++){
            for(int j = 0;j < grid[0].size();j++){
                if(grid[i][j] == '1'){
                    if(i == 0 && j == 0){
                        continue;
                    }else if(i == 0){
                        if(grid[i][j-1] == '1') uf.unit(j,j-1);
                    }else if(j == 0){
                        if(grid[i-1][j] == '1') uf.unit(i*n,(i-1)*n);
                    }else{
                        if(grid[i-1][j] == '1'){
                            uf.unit(i*n+j,(i-1)*n+j);
                        }
                        if(grid[i][j-1] == '1'){
                            uf.unit(i*n+j,i*n+j-1);
                        }
                    }                    
                }
            }
        }
        return uf.island_num();
    }
};

漫水法解法:

class Solution {
public:
    void spread(vector>& grid, int r, int c, char index){
        int size_r = grid.size();
        int size_c = grid[0].size();
        if(r < 0 || r >= size_r || c < 0 || c >= size_c || grid[r][c] != '1') return;
        
        grid[r][c] = index;
        
        spread(grid, r - 1, c, index);
        spread(grid, r, c - 1, index);
        spread(grid, r + 1, c, index);
        spread(grid, r, c + 1, index);
    }
    int numIslands(vector>& grid) {
        int size_r = grid.size();
        if(size_r == 0) return 0;
        int size_c = grid[0].size();
        char ret = '0';
        for(int i = 0;i < size_r;++ i) for(int j = 0;j < size_c;++ j) if(grid[i][j] == '1') spread(grid, i, j, --ret);
        return (ret - '0') * -1;
    }
};

漫水法更加简洁,并且运行时间也比并查集要短。

你可能感兴趣的:(关于并查集和漫水法)