Leetcode130. 被围绕的区域

Every day a Leetcode

题目来源:130. 被围绕的区域

本题给定的矩阵中有三种元素:

  • 字母 X;
  • 被字母 X 包围的字母 O;
  • 没有被字母 X 包围的字母 O。

本题要求将所有被字母 X 包围的字母 O都变为字母 X ,但很难判断哪些 O 是被包围的,哪些 O 不是被包围的。

注意到题目解释中提到:任何边界上的 O 都不会被填充为 X。 我们可以想到,所有的不被包围的 O 都直接或间接与边界上的 O 相连。

我们可以利用这个性质判断 O 是否在边界上,具体地说:

对于每一个边界上的 O,我们以它为起点,标记所有与它直接或间接相连的字母 O;

最后我们遍历这个矩阵,对于每一个字母:

  • 如果该字母被标记过,则该字母为没有被字母 X 包围的字母 O,我们将其还原为字母 O;
  • 如果该字母没有被标记过,则该字母为被字母 X 包围的字母 O,我们将其修改为字母 X。

解法1:深度优先搜索

我们可以使用深度优先搜索实现标记操作。

在下面的代码中,我们把标记过的字母 O 修改为字母 A。

代码:

/** @lc app=leetcode.cn id=130 lang=cpp** [130] 被围绕的区域*/// @lc code=start
class Solution
{
public:// 主函数void solve(vector<vector<char>> &board){if (board.empty())return;int m = board.size(), n = m ? board[0].size() : 0;for (int i = 0; i < m; i++){dfs(board, i, 0);dfs(board, i, n - 1);}for (int j = 0; j < n; j++){dfs(board, 0, j);dfs(board, m - 1, j);}for (int i = 0; i < m; i++)for (int j = 0; j < n; j++){if (board[i][j] == 'A')board[i][j] = 'O';else if (board[i][j] == 'O')board[i][j] = 'X';}}// 辅函数void dfs(vector<vector<char>> &board, int x, int y){int m = board.size(), n = m ? board[0].size() : 0;if (x < 0 || x >= m || y < 0 || y >= n || board[x][y] != 'O')return;board[x][y] = 'A';dfs(board, x + 1, y);dfs(board, x - 1, y);dfs(board, x, y + 1);dfs(board, x, y - 1);}
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n×m),其中 n 和 m 分别为矩阵的行数和列数。深度优先搜索过程中,每一个点至多只会被标记一次。

空间复杂度:O(n×m),其中 n 和 m 分别为矩阵的行数和列数。主要为深度优先搜索的栈的开销。

解法2:广度优先搜索

我们可以使用广度优先搜索实现标记操作。在下面的代码中,我们把标记过的字母 O 修改为字母 A。

代码:

/** @lc app=leetcode.cn id=130 lang=cpp** [130] 被围绕的区域*/// @lc code=start// DFS
//  class Solution
//  {
//  public:
//      // 主函数
//      void solve(vector<vector<char>> &board)
//      {
//          if (board.empty())
//              return;
//          int m = board.size(), n = m ? board[0].size() : 0;
//          for (int i = 0; i < m; i++)
//          {
//              dfs(board, i, 0);
//              dfs(board, i, n - 1);
//          }
//          for (int j = 0; j < n; j++)
//          {
//              dfs(board, 0, j);
//              dfs(board, m - 1, j);
//          }
//          for (int i = 0; i < m; i++)
//              for (int j = 0; j < n; j++)
//              {
//                  if (board[i][j] == 'A')
//                      board[i][j] = 'O';
//                  else if (board[i][j] == 'O')
//                      board[i][j] = 'X';
//              }
//      }
//      // 辅函数
//      void dfs(vector<vector<char>> &board, int x, int y)
//      {
//          int m = board.size(), n = m ? board[0].size() : 0;
//          if (x < 0 || x >= m || y < 0 || y >= n || board[x][y] != 'O')
//              return;
//          board[x][y] = 'A';
//          dfs(board, x + 1, y);
//          dfs(board, x - 1, y);
//          dfs(board, x, y + 1);
//          dfs(board, x, y - 1);
//      }
//  };// BFS
class Solution
{
private:vector<int> direction{-1, 0, 1, 0, -1};public:// 主函数void solve(vector<vector<char>> &board){if (board.empty())return;int m = board.size(), n = m ? board[0].size() : 0;queue<pair<int, int>> q;// 从最外围开始,初始化队列for (int i = 0; i < m; i++){if (board[i][0] == 'O'){q.push(pair<int, int>{i, 0});board[i][0] = 'A';}if (board[i][n - 1] == 'O'){q.push(pair<int, int>{i, n - 1});board[i][n - 1] = 'A';}}for (int j = 0; j < n; j++){if (board[0][j] == 'O'){q.push(pair<int, int>{0, j});board[0][j] = 'A';}if (board[m - 1][j] == 'O'){q.push(pair<int, int>{m - 1, j});board[m - 1][j] = 'A';}}// BFS遍历while (!q.empty()){auto [r, c] = q.front();q.pop();for (int k = 0; k < 4; k++){int x = r + direction[k], y = c + direction[k + 1];if (x < 0 || x >= m || y < 0 || y >= n || board[x][y] != 'O')continue;q.push(pair<int, int>{x, y});board[x][y] = 'A';}}// 最终修改for (int i = 0; i < m; i++)for (int j = 0; j < n; j++){if (board[i][j] == 'A')board[i][j] = 'O';else if (board[i][j] == 'O')board[i][j] = 'X';}}
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n×m),其中 n 和 m 分别为矩阵的行数和列数。广度优先搜索过程中,每一个点至多只会被标记一次。

空间复杂度:O(n×m),其中 n 和 m 分别为矩阵的行数和列数。主要为广度优先搜索的队列的开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/121093.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KC705开发板——MGT IBERT测试记录

本文介绍使用KC705开发板进行MGT的IBERT测试。 KC705开发板 KC705开发板的图片如下图所示。FPGA芯片型号为XC7K325T-2FFG900C。 MGT MGT是 Multi-Gigabit Transceiver的缩写&#xff0c;是Multi-Gigabit Serializer/Deserializer (SERDES)的别称。MGT包含GTP、GTX、GTH、G…

点成案例丨比浊仪助力牙周炎诱发因素研究

牙周炎概述 牙周炎&#xff08;Periodontitis&#xff09;是一种炎症性疾病&#xff0c;其主要特征为牙周袋的形成及袋壁的炎症、牙槽骨吸收而导致牙龈与牙齿分离、牙齿逐渐松动或掉落等。牙周炎主要是由积聚在牙龈及其附近牙面、齿颈缘的牙菌斑内细菌所分泌的毒素令牙周组织发…

2023.9.1 简单认识 JVM

目录 JVM 内存划分 本地方法栈 虚拟机栈 程序计数器 堆区 元数据区 JVM 类加载机制 加载 验证 准备 解析 初始化 类被加载的几种情况&#xff08;懒汉模式 ---> 只要被用到才会被加载&#xff09; 双亲委派模型 JVM 内存划分 JVM 是一个应用程序&#xff0c;在…

QT C++ 基于TCP通信的网络聊天室

一、基本原理及流程 1&#xff09;知识回顾&#xff08;C语言中的TCP流程&#xff09; 2&#xff09;QT中的服务器端/客户端的操作流程 二、代码实现 1&#xff09;服务器 .ui .pro 在pro文件中添加network库 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>…

【MySQL学习笔记】(八)复合查询

在前面的笔记中做的查询基本都是对一张表进行查询&#xff0c;在实际开发中远远不够&#xff0c;本篇文章内容是复合查询相关的笔记。需要用到oracle9i的经典测试表&#xff0c;在笔记&#xff08;六&#xff09;中已经教大家如何导入了。 复合查询 基本查询回顾多表查询子连接…

SpringCloudAlibaba之Sentinel介绍

文章目录 1 Sentinel1.1 Sentinel简介1.2 核心概念1.2.1 资源1.2.2 规则 1.3 入门Demo1.3.1 引入依赖1.3.2 集成Spring1.3.3 Spring中资源规则 1.4 Sentinel控制台1.5 核心原理1.5.1 NodeSelectorSlot1.5.2 ClusterBuilderSlot1.5.3 LogSlot1.5.4 StatisticSlot1.5.5 Authority…

通讯行业:看完这篇文章,我的认知被刷新了!

在现代社会中&#xff0c;通讯系统已经成为我们生活中不可或缺的一部分&#xff0c;它们支撑着信息传递、数据交流和社交互动。然而&#xff0c;通讯系统的可靠性和连续性依赖于电源的稳定供应。电源中断或波动可能导致通讯中断&#xff0c;给个人、企业和组织带来巨大的不便和…

ModuleNotFoundError: No module named ‘transformers.modeling_bart‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【⑰MySQL】 变量 | 循环 | 游标 | 处理程序

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL变量 | 循环 | 游标 | 处理程序的分享✨ 目录 前言1. 变量1.1系统变量1.2 用户变量 2. 定义条件与处理程序2.1 案例分析2.2 定义条件2.3 定义处理程序2.4 案例解决 3. 流程控制3.1 分支结构3.2 循环结构3.3 跳转…

数据通信——传输层TCP(可靠传输机制的滑动窗口)

引言 之前提到过拥塞问题&#xff0c;如果大量数据疯狂涌入&#xff0c;接收端无法及时处理就会导致数据丢包&#xff0c;从而使得通信受到干扰。之前的连续ARQ如果不加以节制&#xff0c;疯狂发送报文&#xff0c;接收端无法及时返回ACK就会导致网络瘫痪。 滑动窗口机制协议 这…

【开发语言】C语言与Python的互操作详解

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

鼠标悬停阴影的效果被旁边div挡住的解决办法

出现的问题 需求要求鼠标悬停某个图片上有阴影效果&#xff0c;但阴影被旁边相邻的div挡住了&#xff0c;如图所示 解决方案 给悬停的这块div增加2个css属性 $(this).css(position, relative); $(this).css(z-index, 200);新的效果如图所示 一直写后端&#xff0c;前端的…

【100天精通Python】Day50:Python Web编程_Django框架从安装到使用

目录 1 安装Django Web框架 2 创建一个Django 项目 3 数据模型 3.1 在应用程序的 models.py 文件中定义数据模 3.2 创建模型的迁移文件并应用 3.2.1 查询模型对象&#xff1a; 3.2.2 创建新模型对象&#xff1a; 3.2.3 更新模型对象&#xff1a; 3.2.4 删除模型对象&a…

【C++ 学习 ⑲】- 多态(下)

目录 一、虚函数表和多态的原理 1.1 - 虚函数表 1.2 - 多态的原理 二、单继承和多继承关系中的虚函数表 2.1 - 单继承关系中的虚函数表 2.2 - 多继承关系中的虚函数表 三、纯虚函数和抽象类 一、虚函数表和多态的原理 1.1 - 虚函数表 问&#xff1a;sizeof(b) 是多少&a…

【9月比赛合集】9场可报名的「创新应用」、「数据分析」和「程序设计」大奖赛,任君挑选!

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 创新应用赛&#xff08;2场比赛&#xff09;程序设计赛&#…

会话跟踪技术学习笔记(Cookie+Session)+ HTTP学习笔记

一、核心知识点&#xff08;重点&#xff09;&#xff1a; 1.1 Cookie 1. Cookie&#xff1a;是一种客户端会话技术&#xff0c;数据会被保存在客户端&#xff0c;Cookie会携带数据访问服务器&#xff0c;用以完成一次会话内多次请求间的数据共享 2. 过程&#xff1a;浏览器…

Android 1.2 开发环境搭建

目录 1.2 开发环境搭建 1.JDK安装与配置 2.开发工具二选一 3.相关术语的解析 4.ADB命令行的一些指令 5.APP程序打包与安装的流程&#xff1a; 6.APP的安装过程&#xff1a; 7.本节小结 1.2 开发环境搭建 现在主流的Android开发环境有: ①Eclipse ADT SDK ②Android Stu…

数据库概念

定义&#xff1a; 数据库&#xff08;Database 简称DB&#xff09;是持久存储有组织/可共享数据/的容器 数据库管理系统(MySQL、Oracle、DB2)是操作/和管理数据库/的软件 分类&#xff1a; 关系(型)数据库 (MySQL、Oracle、SQL Server、SQLite、DB2) 非关系(型)数据库 (Redis…

长胜证券:华为“黑科技”点燃A股炒作激情

8月29日&#xff0c;在未举行相关发布会的情况下&#xff0c;华为新款手机Mate60Pro悄然上线开售&#xff0c;并在一小时内售罄。 金融出资报记者注意到&#xff0c;跟着商场对新机重视的继续发酵&#xff0c;其中的各种技能打破也愈加受到重视&#xff0c;其影响很快扩散到资…

C++ 学习之 构造函数 和 析构函数

前言 总的来说&#xff0c;构造函数负责对象的初始化&#xff0c;而析构函数负责对象的清理和资源释放。它们是C面向对象编程中非常重要的概念&#xff0c;用于管理对象的生命周期&#xff0c;确保对象在创建和销毁时都能够正确地进行初始化和清理。 正文 看代码 class perso…