c_cpp 130.周围地区(Union Find).cpp
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 130.周围地区(Union Find).cpp相关的知识,希望对你有一定的参考价值。
public class Solution {
public void solve(char[][] board) {
if (board.length == 0 || board[0].length == 0) return;
if (board.length < 2 || board[0].length < 2) return;
int m = board.length, n = board[0].length;
for(int i = 0; i < m; i++) {
if(board[i][0] == 'O') {
boundaryDFS(board, i, 0);
}
if(board[i][n - 1] == 'O') {
boundaryDFS(board, i, n - 1);
}
}
for(int j = 0; j < n; j++) {
if(board[0][j] == 'O') {
boundaryDFS(board, 0, j);
}
if(board[m - 1][j] == 'O') {
boundaryDFS(board, m - 1, j);
}
}
for(int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(board[i][j] == 'O') {
board[i][j] = 'X';
}
if(board[i][j] == '*') {
board[i][j] = 'O';
}
}
}
}
private void boundaryDFS(char[][] board, int i, int j) {
board[i][j] = '*';
//去掉等号,否则stack overflow
if(i > 1 && board[i - 1][j] == 'O') {
boundaryDFS(board, i - 1, j);
}
if(i < board.length - 2 && board[i + 1][j] == 'O') {
boundaryDFS(board, i + 1, j);
}
if(j > 1 && board[i][j - 1] == 'O') {
boundaryDFS(board, i, j - 1);
}
if(j < board[i].length - 2 && board[i][j + 1] == 'O') {
boundaryDFS(board, i, j + 1);
}
}
}
class UF
{
private:
int* id; // id[i] = parent of i
int* rank; // rank[i] = rank of subtree rooted at i (cannot be more than 31)
int count; // number of components
public:
UF(int N)
{
count = N;
id = new int[N];
rank = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i;
rank[i] = 0;
}
}
~UF()
{
delete [] id;
delete [] rank;
}
int find(int p) {
while (p != id[p]) {
id[p] = id[id[p]]; // path compression by halving
p = id[p];
}
return p;
}
int getCount() {
return count;
}
bool connected(int p, int q) {
return find(p) == find(q);
}
void connect(int p, int q) {
int i = find(p);
int j = find(q);
if (i == j) return;
if (rank[i] < rank[j]) id[i] = j;
else if (rank[i] > rank[j]) id[j] = i;
else {
id[j] = i;
rank[i]++;
}
count--;
}
};
class Solution {
public:
void solve(vector<vector<char>> &board) {
int n = board.size();
if(n==0) return;
int m = board[0].size();
UF uf = UF(n*m+1);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if((i==0||i==n-1||j==0||j==m-1)&&board[i][j]=='O') // if a 'O' node is on the boundry, connect it to the dummy node
uf.connect(i*m+j,n*m);
else if(board[i][j]=='O') // connect a 'O' node to its neighbour 'O' nodes
{
if(board[i-1][j]=='O')
uf.connect(i*m+j,(i-1)*m+j);
if(board[i+1][j]=='O')
uf.connect(i*m+j,(i+1)*m+j);
if(board[i][j-1]=='O')
uf.connect(i*m+j,i*m+j-1);
if(board[i][j+1]=='O')
uf.connect(i*m+j,i*m+j+1);
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!uf.connected(i*m+j,n*m)){ // if a 'O' node is not connected to the dummy node, it is captured
board[i][j]='X';
}
}
}
}
};
Hi. So here is my accepted code using Union Find data structure. The idea comes from the observation that if a region is NOT captured, it is connected to the boundry. So if we connect all the 'O' nodes on the boundry to a dummy node, and then connect each 'O' node to its neighbour 'O' nodes, then we can tell directly whether a 'O' node is captured by checking whether it is connected to the dummy node.
For more about Union Find, the first assignment in the algo1 may help:
https://www.coursera.org/course/algs4partI
以上是关于c_cpp 130.周围地区(Union Find).cpp的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 130.周围地区(Union Find).cpp
c_cpp 130.周围地区(Union Find).cpp
c_cpp 130.周围地区(Union Find).cpp