leetcode 130. Surrounded Regions 典型的深度优先遍历DFS + 矩阵遍历

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

从矩形最外面一圈开始逐渐向里拓展。 若 O 是在矩形最外圈,它肯定不会被 X 包围,与它相连(邻)的 O 也就不可能被 X 包围,也就不会被替换,所以我们的工作主要是找出:
1)最外圈的 O
2)与最外圈的 O 相连的 O
3) 将上述找到的元素替换为某种标识符,代码中使用“#”
4.)最后按先行后列的顺序遍历矩形,找到没有被替换为 O 的元素,它们就是被 X 完全包围的需要被替换为 X 的元素;同时,标记为 # 的元素是没有被 X 包围的元素,此时将它们变回原来的 O

这道题的亮点是从问题的对立面来考虑做得,是很经典的DFS深度优先遍历的做法,很棒

代码如下:

import java.util.Stack;

class Point
{
    int row;
    int col;
    Point(int a,int b)
    {
        row = a;
        col =b;
    }
}

/*
 * 这个用来学习BFS和DFS很有用
 * 
 * 本题是要求把所有的内部的O替换为X,但是矩阵边界的O不算,
 * 本题是从反面来考虑的,把所有不能替换的O使用*来做一个标记
 * 
 * 本题是通过stack来完成深度优先遍历的,使用BFS或者递归去做
 * 是同样的做法
 * 
 * */
public class Solution
{
    public void solve(char[][] board) 
    {
        if(board==null || board.length<=0)
            return;

        int row = board.length;
        int col = board[0].length;
        if(row<=2 || col<=2)
            return;
        boolean [][]visit = new boolean[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)
                        dfs(visit,board,i,j,row,col);
                }
            }
        }

        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {
                if(board[i][j]=='*')
                    board[i][j]='O';
                else if(board[i][j]=='O')
                    board[i][j]='X';
            }
        }
    }

    private void dfs(boolean [][]visit,char[][] board, int x, int y, int row, int col) 
    {
        board[x][y]='*';
        Stack<Point> stack = new Stack<>();
        stack.push(new Point(x,y));
        visit[x][y]=true;

        while(stack.empty()==false)
        {
            Point top = stack.peek();
            stack.pop();
            if(top.row>0 && board[top.row-1][top.col]=='O' && visit[top.row-1][top.col]==false)
            {
                board[top.row-1][top.col]='*';
                visit[top.row-1][top.col]=true;
                stack.push(new Point(top.row-1, top.col));
            }

            if(top.row+1<row && board[top.row+1][top.col]=='O' && visit[top.row+1][top.col]==false)
            {
                board[top.row+1][top.col]='*';
                visit[top.row+1][top.col]=true;
                stack.push(new Point(top.row+1, top.col));
            }

            if(top.col>0 && board[top.row][top.col-1]=='O' && visit[top.row][top.col-1]==false)
            {
                board[top.row][top.col-1]='*';
                visit[top.row][top.col-1]=true;
                stack.push(new Point(top.row, top.col-1));
            }

            if(top.col+1<col && board[top.row][top.col+1]=='O' && visit[top.row][top.col+1]==false)
            {
                board[top.row][top.col+1]='*';
                visit[top.row][top.col+1]=true;
                stack.push(new Point(top.row, top.col+1));
            }   
        }
    }
}

下面是C++的做法,就是做一个DFS深度优先遍历,不过这道题我们是反其道而行之,通过寻找不符合条件的O,标记为*,然后把剩下的O填充为X即可完成本体的所有要求

代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
#include <iomanip>
#include <cstdlib>
#include <ctime>

using namespace std;



class Solution 
{
public:
    void solve(vector<vector<char>>& b) 
    {
        if (b.size() <= 0)
            return;
        int row = b.size(), col = b[0].size();
        vector<vector<bool>> visit(row, vector<bool>(col, false));
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                if (i == 0 || i == row - 1 || j == 0 || j == col - 1)
                    dfs(b,visit, i, j);
            }
        }

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                if (b[i][j] == 'O')
                    b[i][j] = 'X';
                else if(b[i][j] == '*')
                    b[i][j] = 'O';
            }
        }
    }

    void dfs(vector<vector<char>>& b, vector<vector<bool>>& visit, int x, int y)
    {
        int row = b.size(), col = b[0].size();
        if (x < 0 || x >= row || y < 0 || y >= col || visit[x][y] == true || b[x][y] != 'O')
            return;
        else
        {
            visit[x][y] = true;
            b[x][y] = '*';
            dfs(b, visit, x - 1, y);
            dfs(b, visit, x + 1, y);
            dfs(b, visit, x, y - 1);
            dfs(b, visit, x, y + 1);
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于LeetCode上的问题994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值