资讯专栏INFORMATION COLUMN

【LC总结】Union Find系列(Num of Islands I&II/Graph V

bergwhite / 2217人阅读

摘要:不得不说,对于这道题而言,是一种很木讷的模板。主函数按矩阵大小建立一个类进行后续操作一个结点用来连接边角不可能被围绕的一个函数对矩阵元素进行结点线性化。同理,,,在主函数中初始化后调用。

Surrounded Regions Problem

Given a 2D board containing "X" and "O" (the letter O), capture all regions surrounded by "X".

A region is captured by flipping all "O"s into "X"s in that surrounded region.

For example,

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X
Note

不得不说,对于这道题而言,Union Find是一种很木讷的模板。

主函数:按矩阵大小建立:

一个UnionFind类进行后续操作;

一个dummy结点用来连接边角不可能被X围绕的O;

一个node()函数对矩阵元素进行结点线性化。

操作:

遍历所有结点,矩阵边角的O与dummy相连,矩阵内部的O与相邻的O相连;

遍历所有结点,与dummy相连的结点设置为O,其它所有结点设置为X。

UnionFind函数:建立:

全局变量parents;

初始化函数UnionFind(int size);

查找parents函数find(int node);

归并函数union(int node1, int node2);

测试两结点是否相连函数isConnected(int node1, int node2);

操作:

find(int node): 用while循环向上查找node的parent,注意先向上迭代parents[node],再迭代node,否则会超时;

union(int node1, int node2): 找到两个结点的parents,r1和r2,令parents[r1] = r2;

isConnected(int n1, int n2): 查看两个结点的parents是否相等。

Solution
public class Solution {
    int row, col;
    public void solve(char[][] board) {
        if (board == null || board.length == 0) return;
        row = board.length;
        col = board[0].length;
        UnionFind uf = new UnionFind(row*col+1);
        int dummy = row*col;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (board[i][j] == "O") {
                    if (i == 0 || i == row-1 || j == 0 || j == col-1) uf.union(node(i, j), dummy);
                    else {
                        if (i > 0 && board[i-1][j] == "O") uf.union(node(i, j), node(i-1, j));
                        if (i > 0 && board[i+1][j] == "O") uf.union(node(i, j), node(i+1, j));
                        if (j > 0 && board[i][j-1] == "O") uf.union(node(i, j), node(i, j-1));
                        if (j > 0 && board[i][j+1] == "O") uf.union(node(i, j), node(i, j+1));
                    }
                }
            }
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (uf.isConnected(node(i, j), dummy)) board[i][j] = "O";
                else board[i][j] = "X";
            }
        }
    }
    public int node(int i, int j) {
        return i*col+j;
    }
}

class UnionFind {
    int[] parents;
    public UnionFind(int n) {
        parents = new int[n];
        for (int i = 0; i < n; i++) parents[i] = i;
    }
    public void union(int n1, int n2) {
        int r1 = find(n1);
        int r2 = find(n2);
        if (r1 != r2) parents[r1] = r2;
    }
    public int find(int node) {
        if (parents[node] == node) return node;
        parents[node] = find(parents[node]);
        return parents[node];
    }    
    public boolean isConnected(int n1, int n2) {
        return find(n1) == find(n2);
    }
}
Graph Valid Tree Problem

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

For example:

Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.

Note

同理,find,union,在主函数中初始化后调用。

Solution
public class Solution {
    int[] parents;
    public boolean validTree(int n, int[][] edges) {
        if (edges.length != n-1) return false;
        parents = new int[n];
        for (int i = 0; i < n; i++) parents[i] = i;
        for (int i = 0; i < n-1; i++) {
            if (find(edges[i][0]) == find(edges[i][1])) return false;
            union(edges[i][0], edges[i][1]);
        }
        return true;
    }
    public int find(int n) {
        if (parents[n] == n) return n;
        parents[n] = find(parents[n]);
        return parents[n];
    }
    public void union(int n1, int n2) {
        int r1 = find(n1);
        int r2 = find(n2);
        if (r1 != r2) parents[r1] = r2;
    }
}
Number of Islands Problem

Given a 2d grid map of "1"s (land) and "0"s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3

Note Solution
public class Solution {

    class UnionFind {
        public int count;
        public int[] parents;
        public UnionFind(int m, int n, char[][] grid) {
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (grid[i][j] == "1") count++;
                }
            }
            parents = new int[m*n];
            for (int i = 0; i < m*n; i++) parents[i] = i;
        }
        public int find(int i) {
            if (i == parents[i]) return i;
            parents[i] = find(parents[i]);
            return parents[i];
        }
        public void union(int i, int j) {
            int pi = find(i);
            int pj = find(j);
            if (pi == pj) return;
            else parents[pi] = pj;
            count--;
        }
        public boolean isConnected(int i, int j) {
            return find(i) == find(j);
        }
    }
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;
        int m = grid.length, n = grid[0].length;
        UnionFind uf = new UnionFind(m, n, grid);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == "0") continue;
                int x = i*n+j;
                int y;
                if (i < m-1 && grid[i+1][j] == "1") {
                    y = x+n;
                    uf.union(x, y);
                }
                if (j < n-1 && grid[i][j+1] == "1") {
                    y = x+1;
                    uf.union(x, y);
                }
            }
        }
        return uf.count;
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66059.html

相关文章

  • Leetcode之Union-Find(并查集)

    摘要:并查集包括查询和联合,主要使用不相交集合查询主要是用来决定不同的成员是否在一个子集合之内联合主要是用来把多个子集合成一个集合的实际运用计算机网络检查集群是否联通电路板检查不同的电路元件是否联通初始化联通与检测与是否联通返回联通的数 并查集(Union-Find)包括查询(Find)和联合(Union),主要使用不相交集合(Disjoint-Sets)查询(Find)主要是用来决定不同的...

    roland_reed 评论0 收藏0
  • [LeetCode/LintCode] Number of Islands [DFS]

    摘要:两个循环遍历整个矩阵,出现则将其周围相邻的全部标记为,用子函数递归标记。注意里每次递归都要判断边界。写一个的,写熟练。 Number of Islands Problem Given a boolean/char 2D matrix, find the number of islands. 0 is represented as the sea, 1 is represented as...

    Fourierr 评论0 收藏0
  • 323. Number of Connected Components in an Undirect

    摘要:题目链接这道题和是一个思路,一个初始化为,每次有新的就两个节点,如果两个节点原来不在一个连通图里面就减少并且连起来,如果原来就在一个图里面就不管。用一个索引来做,优化就是加权了,每次把大的树的当做,小的树的作为。 323. Number of Connected Components in an Undirected Graph 题目链接:https://leetcode.com/pr...

    zsy888 评论0 收藏0
  • leetcode200. Number of Islands

    摘要:题目要求提供一个二维数组表示一张地图,其中代表陆地,代表海洋。这里使用一个新的二维数组来表示对应地图上的元素属于哪个并查集。在合并的时候先进行判断,如果二者为已经相连的陆地,则无需合并,否则将新的二维数组上的元素指向所在的并查集。 题目要求 Given a 2d grid map of 1s (land) and 0s (water), count the number of isla...

    Zoom 评论0 收藏0
  • 怎样依据python完成单眼三维成像详细说明

      单眼三维成像是依据单独监控摄像头健身运动仿真模拟双目视觉获得物件和空间里的三维视觉信息内容,下面本文关键为大家介绍了对于如何依据python完成单眼三维成像的资料,原文中依据案例编码推荐的十分详尽,必须的小伙伴可以借鉴一下  一、单眼三维成像简述  客观现实的物件是三维立体的,而我用监控摄像头获得的图象是二维动画的,但我们可以依据二维图像认知总体目标三维信息内容。三维重建技术要以相对应的形式解...

    89542767 评论0 收藏0

发表评论

0条评论

bergwhite

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<