surrounded regions java,[Leetcode] Surrounded Regions 找出被包围的区域

Surrounded Regions

Given a 2D board containing 'X' and '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

边缘搜索替换法

复杂度

时间 O(MN) 空间 O(MN)

思路

从矩阵的四条边上的点作为起点,搜索连续的一块区域上值为O的点并赋为一个临时变量。这里我们用BFS或DFS进行搜索。对四条边上所有点都进行过这个步骤后,矩阵内剩余的O就是被包围的O。此时再对所有点遍历一遍,将临时变量赋回O,而剩余的O则赋为X。

注意

用队列实现BFS时,赋临时变量B时要在将周边点加入队列时就赋值,减少while循环的次数,否则Leetcode会超时

代码

广度优先 BFS

public class Solution {

public void solve(char[][] board) {

for(int i = 0; i < board.length; i++){

for(int j = 0; j < board[0].length; j++){

if((i == 0 || j == 0 || i == board.length - 1 || j == board[0].length - 1) && (board[i][j]=='O')){

Queue q = new LinkedList();

q.offer(i * board[0].length + j);

board[i][j] = 'B';

while(!q.isEmpty()){

Integer key = q.poll();

int x = key / board[0].length;

int y = key % board[0].length;

if(x > 0 && board[x-1][y]=='O'){

q.offer((x-1) * board[0].length + y);

board[x-1][y] = 'B';

}

if(x < board.length - 1 && board[x+1][y]=='O'){

q.offer((x+1) * board[0].length + y);

board[x+1][y] = 'B';

}

if(y > 0 && board[x][y-1]=='O'){

q.offer(x * board[0].length + y - 1);

board[x][y-1] = 'B';

}

if(y < board[0].length - 1 && board[x][y+1]=='O'){

q.offer(x * board[0].length + y + 1);

board[x][y+1] = 'B';

}

}

}

}

}

for(int i = 0; i < board.length; i++){

for(int j = 0; j < board[0].length; j++){

if(board[i][j]=='O') board[i][j]='X';

if(board[i][j]=='B') board[i][j]='O';

}

}

}

}

深度优先 DFS

public class Solution {

static class Pair {

public int first;

public int second;

public Pair(int f, int s) {

first = f;

second = s;

}

}

public void solve(char[][] board) {

if(board == null || board.length == 0) {

return ;

}

for(int i = 0; i < board[0].length; ++i) {

if(board[0][i] == 'O') {

markUnflippable(board,0,i);

}

}

for(int i = 0; i < board[board.length-1].length; ++i) {

if(board[board.length-1][i] == 'O') {

markUnflippable(board,board.length-1,i);

}

}

for(int i = 0 ; i < board.length; ++i) {

if(board[i][0] == 'O') {

markUnflippable(board,i,0);

}

}

for(int i =0; i < board.length; ++i) {

if(board[i][board[i].length-1] == 'O') {

markUnflippable(board,i,board[i].length-1);

}

}

// modify the board

for(int i = 0; i < board.length; ++i) {

for(int j = 0; j < board[i].length; ++j) {

if(board[i][j] == 'O') {

board[i][j] = 'X';

} else if(board[i][j] == 'U') {

board[i][j] = 'O';

}

}

}

}

public void markUnflippable(char[][] board, int r, int c) {

int[] dirX = {-1,0,1,0};

int[] dirY = {0,1,0,-1};

ArrayDeque stack = new ArrayDeque<>();

stack.push(new Pair(r,c));

while(!stack.isEmpty()) {

Pair p = stack.pop();

board[p.first][p.second] = 'U';

for(int i = 0; i < dirX.length; ++i) {

if(p.first + dirX[i] >= 0 && p.first + dirX[i] < board.length && p.second + dirY[i] >= 0 && p.second +dirY[i] < board[p.first + dirX[i]].length && board[p.first+dirX[i]][p.second+dirY[i]] == 'O') {

stack.push(new Pair(p.first+dirX[i],p.second+dirY[i]));

}

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里提供一种基于深度优先搜索(DFS)算法的解决方案,具体实现如下: ```lua -- 定义一个函数,用于判断某个元素所在的连通区域是否被其他连通区域完全包围 function is_surrounded(grid, row, col) -- 定义一个标记数组,用于记录每个元素是否已经被遍历过 local visited = {} for i = 1, #grid do visited[i] = {} for j = 1, #grid[i] do visited[i][j] = false end end -- 定义一个函数,用于执行深度优先搜索 local function dfs(r, c) -- 如果当前元素已经被遍历过,直接返回 if visited[r][c] then return end -- 标记当前元素为已遍历 visited[r][c] = true -- 如果当前元素位于边界上,说明它所在的连通区域没有被完全包围 if r == 1 or r == #grid or c == 1 or c == #grid[1] then return true end -- 递归遍历当前元素的上下左右四个方向 if dfs(r-1, c) or dfs(r+1, c) or dfs(r, c-1) or dfs(r, c+1) then return true end return false end -- 执行深度优先搜索,并返回结果 return dfs(row, col) end ``` 该函数接受三个参数:一个表示网格的二维数组 `grid`,一个表示元素所在行的索引 `row`,以及一个表示元素所在列的索引 `col`。函数首先创建一个和 `grid` 一样大小的标记数组 `visited`,并将其中所有元素初始化为 `false`。然后定义一个内部函数 `dfs`,用于执行深度优先搜索。该函数首先判断当前元素是否已经被遍历过,如果是则直接返回;否则将当前元素标记为已遍历,并检查当前元素是否位于边界上。如果是,则说明它所在的连通区域没有被完全包围,可以直接返回 `true`;否则递归遍历当前元素的上下左右四个方向,并将搜索结果作为返回值。最后,执行 `dfs(row, col)` 并返回其结果即可。 使用示例: ```lua -- 定义一个二维数组表示网格 local grid = { {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, } -- 判断第二行第二列的元素所在的连通区域是否被其他连通区域完全包围 local surrounded = is_surrounded(grid, 2, 2) print(surrounded) -- 输出 false ``` 在上面的示例中,我们定义了一个二维数组 `grid` 表示一个 4x4 的网格,其中 1 表示障碍物,0 表示空地。然后调用 `is_surrounded(grid, 2, 2)` 函数,判断第二行第二列的元素所在的连通区域是否被其他连通区域完全包围。由于该连通区域没有被完全包围,因此返回值为 `false`。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值