並查集(UnionFind) 系列
547.Number of Provinces
MediumThere aren
cities. Some of them are connected, while some are not. If citya
is connected directly with cityb
, and cityb
is connected directly with cityc
, then citya
is connected indirectly with cityc
.
Aprovinceis a group of directly or indirectly connected cities and no other cities outside of the group.
You are given ann x n
matrixisConnected
whereisConnected[i][j] = 1
if theith
city and thejth
city are directly connected, andisConnected[i][j] = 0
otherwise.
Returnthe total number ofprovinces.
Example 1:
Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]] Output: 2
Example 2:
Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]] Output: 3
Constraints:
1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j]
is1
or0
.isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]
解法1: 並查集
class Solution { public int findCircleNum(int[][] isConnected) { //1.for loop len elements do unionfind UnionFind uf = newUnionFind(isConnected.length); for(int i=0;i<isConnected.length;i++){ for(int j=0;j<isConnected.length;j++){ if(i!=j && isConnected[i][j]==1) { uf.union(i,j); } } } //2.count the parent[i]=i int count = 0; for(int i=0;i<isConnected.length;i++) if(uf.parent[i]==i) count++; return count; } //UnionFind implementation class UnionFind{ int[] parent; int[] rank; UnionFind(int n){ parent = new int[n]; rank = new int[n]; for(int i=0;i<n;i++) parent[i]=i; } public int findParent(int x){ if(x==parent[x]) return x; parent[x] = findParent(parent[x]); return parent[x]; } public void union( int x,int y ){ int px = findParent(x); int py = findParent(y); if(px==py) return; if(rank[px]>rank[py]) parent[py]=px; else if(rank[px]<rank[py]) parent[px]=py; else{ parent[px]=py; rank[py]++; } } } }
解法二: dfs
class Solution { public int findCircleNum(int[][] isConnected) { //defind visited int len = isConnected.length; boolean[] visited = new boolean[len]; //for loop 0 ~ len-1 recursively find its connections int count = 0; for(int i=0;i<len;i++){ if(visited[i]) continue; count++; dfs(isConnected,i,visited); } return count; } private void dfs(int[][] isConnected,int i,boolean[] visited){ int len = isConnected.length; visited[i]=true; for(int j=0;j<len;j++){ if(isConnected[i][j]==1 && !visited[j] ) dfs(isConnected,j,visited); } } }434 · Number of Islands II Algorithms Medium Description
Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y means that you can change the grid matrix[A[i].x][A[i].y] from sea to island. Return how many island are there in the matrix after each operator.You need to return an array of size K.
0 is represented as the sea, 1 is represented as the island. If two 1 is adjacent, we consider them in the same island. We only consider up/down/left/right adjacent.
ExampleExample 1:
Input: n = 4, m = 5, A = [[1,1],[0,1],[3,3],[3,4]]
Output: [1,1,2,2]
Explanation:
0. 00000
00000
00000
00000
1. 00000
01000
00000
00000
2. 01000
01000
00000
00000
3. 01000
01000
00000
00010
4. 01000
01000
00000
00011
Example 2:
Input: n = 3, m = 3, A = [[0,0],[0,1],[2,2],[2,1]]
Output: [1,1,2,2]
/** * Definition for a point. * class Point { * int x; * int y; * Point() { x = 0; y = 0; } * Point(int a, int b) { x = a; y = b; } * } */ public class Solution { /** * @param n: An integer * @param m: An integer * @param operators: an array of point * @return: an integer array */ public List<Integer> numIslands2(int m, int n, Point[] operators) { List<Integer> result = new ArrayList(); UnionFind uf = new UnionFind(m*n); int count=0; int[][] directions = new int[][]{{-1,0},{1,0},{0,-1},{0,1}}; boolean[][] visited = new boolean[m][n]; if(operators==null) return result; for(Point p:operators){ //重複元素直接跳過 if(visited[p.x][p.y]) {//坑點1:重複元素記得跳過 result.add(count); continue; } count++; visited[p.x][p.y]=true; for(int[] dir:directions){ int nx = p.x+dir[0]; int ny = p.y+dir[1]; if( nx>=0 && ny>=0 && nx<m && ny<n ){ if(visited[nx][ny] && (uf.find(nx*n+ny)!=uf.find(p.x*n+p.y))){//坑點2:這裡的列數是n,不是m, 因此是p.x*n+p.y ,另外當且僅當相鄰點已經被訪問過並且還沒有連通的情況下才進行連通並count-- count--; uf.union(p.x*n+p.y,nx*n+ny); } } } result.add(count); } return result; } class UnionFind{ int[] parent; UnionFind(int n){ parent = new int[n]; for(int i=0;i<n;i++) parent[i]=i; } int find(int x){ if(x==parent[x]) return x; parent[x] = find(parent[x]); return parent[x]; } void union(int x,int y){ int px = find(x); int py = find(y); if(px==py) return; parent[px]=py; } } }