Leetcode 130. Surrounded Regions

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.
在这里插入图片描述
Explanation:

Surrounded regions shouldn’t be on the border, which means that any ‘O’ on the border of the board are not flipped to ‘X’. Any ‘O’ that is not on the border and it is not connected to an ‘O’ on the border will be flipped to ‘X’. Two cells are connected if they are adjacent cells connected horizontally or vertically.

method 1 DFS

深度优先遍历,将每一个和边界O联系的点都先设为E,最后再将O设置为X,将E设置回O

void helper_(vector<vector<char>>& board, int i, int j){
	if (board[i][j] == 'X' || board[i][j] == 'E') return;
	int dirc[] = { 0, 1, 0, -1, 0 };
	board[i][j] = 'E';
	int m = board.size(), n = board[i].size();
	for (int k = 0; k < 4; k++){
		int x = i + dirc[k];
		int y = j + dirc[k + 1];
		if (x < 0 || y < 0 || x == m || y == n || board[x][y] == 'X' || board[x][y] == 'E')
			continue;
		helper_(board, x, y);
	}
}

void solve2(vector<vector<char>>& board) {
	if (board.size() == 0) return;

	int m = board.size(), n = board[0].size();
	for (int i = 0; i < board.size(); i++){
		for (int j = 0; j < board[i].size(); j++){
			if (i == 0 || j == 0 || i == m - 1 || j == n - 1){
				if (board[i][j] == 'O')
					helper_(board, i, j);
			}
		}
	}

	for (int i = 0; i < board.size(); i++){
		for (int j = 0; j < board[i].size(); j++){
			if (board[i][j] == 'O') board[i][j] = 'X';
			else if (board[i][j] == 'E') board[i][j] = 'O';
		}
	}
}

method 2 union find

在做本题一直卡着的点:
重点1: unite,要知道是把谁union到谁
重点2: 要把四周往新结点 union。向上和向左代表之前的结点,如果之前结点的根为dummyNode,那么本结点也要,如果之前的结点的根并非dummyNode,那么要把之前的结点往新结点union,因为之后该新结点可能会union更新的结点
重点3: 因为边界的特殊性,所以不能再从4个方向union,这样会影响边界原本正确的根节点,所以只能从上,从左两个方向,这样就不会反复union

vector<int> pa;

int find(int n) {
	return pa[n] == n ? n : pa[n] = find(pa[n]);
}

void unite(int n1, int n2) {
	int p1 = find(n1);
    int p2 = find(n2);
    if (p1 == pa.size()-1) {
        pa[p2] = p1;
    } else {
        pa[p1] = p2;
    }
}

void solve(vector<vector<char>>& board) {
	if (board.empty() || board[0].empty()) {
		return;
	}
	int rows = board.size(), cols = board[0].size();
	pa.resize(rows * cols + 1);
	for (int i = 0; i < pa.size(); ++i) {
		pa[i] = i;
	}

	int dummyNode = pa.size()-1;
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			if (board[i][j] == 'X') {
				continue;
			}

			if (i == 0 || j == 0 || i == rows-1 || j == cols - 1) {
				unite(dummyNode, i * cols + j);
			}
			if (i > 0 && board[i-1][j] == 'O') {
				unite((i - 1) * cols + j, i * cols + j);
			}
			if (j > 0 && board[i][j-1] == 'O') {
				unite( i * cols + j-1, i * cols + j);
			}
		}
	}

	for (int i = 0; i < rows; i++){
		for (int j = 0; j < cols; j++){
			if (board[i][j] == 'O' && find(i * cols + j) != dummyNode) 
                board[i][j] = 'X';
		}
	}
	
}

summary

  1. 将数组中不能改变的元素设置为其他值,最后再改回来,这样就避免了访问数组的使用,但要小心当改变元素的值会对周围元素是否改变值产生影响时,要慎重,如leetcode 73. Set Matrix Zeroes、Leetcode 289. Game of Life

  2. 引入dummyNode指向特殊节点!

  3. 注意遍历的方向,有时并不是要往四个方向都搜索,如在本题四个方向都搜索会造成重复union,最后导致错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值