【LeetCode每日一题】【BFS模版与例题】【二维数组】130被围绕的区域 994 腐烂的橘子

前几天写过一篇BFS比较基础版的遍历
【LeetCode每日一题】【BFS模版与例题】863.二叉树中所有距离为 K 的结点

,可以先看一下再看本文

用 BFS 算法遍历二维数组

遍历二维矩阵:二维矩阵中的一个位置看做一个节点,这个节点的上下左右四个位置就是相邻节点。

130 被围绕的区域

在这里插入图片描述

解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的’O’ 都不会被填充为’X’。 任何不在边界上,或不与边界上的’O’ 相连的’O’ 最终都会被填充为’X’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

思路:

遍历二维数组,找到边界为‘o’的点,利用BFS非递归框架将与之相连的’o‘都替换为随便一个字母,这里替换’#’。剩下的‘o’就是不与边界连接的 ‘o’。

/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var solve = function (board) {
  let m = board.length
  let n = board[0].length
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
		// 从边界的‘o’出发
      let flag = i === 0 || j === 0 || i === m - 1 || j === n - 1
      if (flag && board[i][j] === 'O') {
        bfs(board, i, j)
      }
    }
  }

 // 对操作后的数组进行刷新。
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
		// 被包围的,可以去除
      if (board[i][j] === 'O') {
        board[i][j] = 'X'
      }
		// 边界的,不可以去除,还原回来。
      if (board[i][j] === '#') {
        board[i][j] = 'O'
      }
    }
  }

  return board
}

const bfs = (board, i, j) => {
  let queue = []
  let visited = new Set()
  queue.push([i, j])
  visited.add(`${i},${j}`)

  while (queue.length > 0) {
    let [x, y] = queue.shift()
    board[x][y] = '#'

    // 向上
    if (
      x - 1 >= 0 &&
      board[x - 1][y] === 'O' &&
      !visited.has(`${x - 1},${y}`)
    ) {
      queue.push([x - 1, y])
      visited.add(`${x - 1},${y}`)
    }

    // 向下
    if (
      x + 1 < board.length &&
      board[x + 1][y] === 'O' &&
      !visited.has(`${x + 1},${y}`)
    ) {
      queue.push([x + 1, y])
      visited.add(`${x - 1},${y}`)
    }

    // 向左
    if(y - 1 >= 0 && board[x][y - 1] === 'O' && !visited.has(`${x},${y - 1}`)){
      queue.push([x, y - 1])
      visited.add(`${x},${y - 1}`)
    }

    // 向右
    if(y + 1 < board[0].length && board[x][y + 1] === 'O' && !visited.has(`${x},${y + 1}`)){
      queue.push([x, y + 1])
      visited.add(`${x},${y + 1}`)
    }
  }
}

994 腐烂的橘子

在这里插入图片描述

错误的思路:

遍历二维数组,找到腐烂的橘子,利用这个橘子BFS搜索附近的橘子,记录将连接的橘子变成烂橘子的时间。将二维数组中烂橘子将其他橘子变成烂橘子的时间相加。

错误的题解。

/**
 * @param {number[][]} grid
 * @return {number}
 */
var orangesRotting = function (grid) {
  if (!grid.flat().includes(1)) {
    return 0;
  }

  let step = -1;
  let row = grid.length;
  let col = grid[0].length;

  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (grid[i][j] == 2) {
        step += bfs(grid, i, j);
      }
    }
  }
  if (grid.flat().includes(1)) {
    return -1;
  }
  return step;
};

const bfs = (grid, i, j) => {
  let queue = [[i, j]];
  let visited = new Set();
  visited.add(`${i},${j}`);

  let step = 0;

  while (queue.length) {
    let size = queue.length;
    for (let k = 0; k < size; k++) {
      let [x, y] = queue.shift();
      grid[x][y] = 0;

      // 向上
      if (x - 1 >= 0 && grid[x - 1][y] == 1 && !visited.has(`${x - 1},${y}`)) {
        queue.push([x - 1, y]);
        visited.add(`${x - 1},${y}`);
      }

      // 向下
      if (
        x + 1 < grid.length &&
        grid[x + 1][y] == 1 &&
        !visited.has(`${x + 1},${y}`)
      ) {
        queue.push([x + 1, y]);
        visited.add(`${x + 1},${y}`);
      }

      // 向左
      if (y - 1 >= 0 && grid[x][y - 1] == 1 && !visited.has(`${x},${y - 1}`)) {
        queue.push([x, y - 1]);
        visited.add(`${x},${y - 1}`);
      }

      // 向右
      if (
        y + 1 < grid[0].length &&
        grid[x][y + 1] == 1 &&
        !visited.has(`${x},${y + 1}`)
      ) {
        queue.push([x, y + 1]);
        visited.add(`${x},${y + 1}`);
      }
    }
    step++;
  }
  return step;
};

错误的原因:

假如二维数组左上角和右下角分别有一个烂橘子。它们应该能够同时让四周的橘子变烂,而不是先后顺序的。因此,多源的BFS,应该将每个源都放置在queue里面。

var orangesRotting = function (grid) {
 // 特殊情况:本来就没有新鲜橘子的。
  if (!grid.flat().includes(1)) {
    return 0;
  }

  let step = -1;
  let row = grid.length;
  let col = grid[0].length;

  let queue = [];
  let visited = new Set();

  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
		
			// 多源,每个烂橘子都应该放在queue,他们是属于同一层的。
      if (grid[i][j] == 2) {
        queue.push([i, j]);
        visited.add(`${i},${j}`);
      }
    }
  }

  step += bfs(grid, queue, visited);
	
	// 如果依然剩下新鲜的橘子,说明无法完成,返回-1;
  if (grid.flat().includes(1)) {
    return -1;
  }

  return step;
};

const bfs = (grid, queue, visited) => {

  let step = 0;
  while (queue.length) {

    let size = queue.length;
    for (let k = 0; k < size; k++) {
			
			// 将节点置为0
      let [x, y] = queue.shift();
      grid[x][y] = 0;

			// 向相邻的节点扩散。
      // 向上
      if (x - 1 >= 0 && grid[x - 1][y] != 0 && !visited.has(`${x - 1},${y}`)) {
        queue.push([x - 1, y]);
        visited.add(`${x - 1},${y}`);
      }

      // 向下
      if (
        x + 1 < grid.length &&
        grid[x + 1][y] != 0 &&
        !visited.has(`${x + 1},${y}`)
      ) {
        queue.push([x + 1, y]);
        visited.add(`${x + 1},${y}`);
      }

      // 向左
      if (y - 1 >= 0 && grid[x][y - 1] != 0 && !visited.has(`${x},${y - 1}`)) {
        queue.push([x, y - 1]);
        visited.add(`${x},${y - 1}`);
      }

      // 向右
      if (
        y + 1 < grid[0].length &&
        grid[x][y + 1] != 0 &&
        !visited.has(`${x},${y + 1}`)
      ) {
        queue.push([x, y + 1]);
        visited.add(`${x},${y + 1}`);
      }
    }
		// 每层遍历完都需要添加1分钟
    step++;
  }
  return step;
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gRPC入门

文章目录 1. 简介2. 安装gRPC2.1. 下载protobuf2.2. 安装grpc核心库2.3. 安装protoc的Go插件2.4. 检查 3. 入门示例4. proto文件介绍5. 服务端代码编写6. 客户端代码编写7. 认证以及安全传输 1. 简介 在 gRPC 中&#xff0c;客户端应用程序可以像本地对象一样直接调用不同机器…

Flutter中的Provider状态管理工具有哪些优势

在Flutter应用开发中&#xff0c;状态管理是一个至关重要的方面。而Provider作为一种简单、灵活且高效的状态管理工具&#xff0c;在众多Flutter开发者中备受青睐。本文将深入探讨Provider在Flutter中的优势&#xff0c;帮助读者更好地理解其价值和应用场景。 简单易用 Provi…

《数字图像处理(MATLAB版)》相关算法代码及其分析(3)

目录 1 对边界进行子采样 1.1 输入参数检查 1.2 处理重复坐标 1.3 计算边界最大范围 1.4 确定网格线数量 1.5 构建网格位置向量 1.6 计算曼哈顿距离 1.7 整理输出结果 1.8 返回结果 2 改变图像的存储类别 2.1 函数输入 2.2 数据类型转换 2.3 错误处理 2.4 返回结…

Flutter整体框架

Flutter整体框架由三部分组成&#xff1a;Framework、Engine和Embedder。 Framework Framework提供了一个用 Dart 语言编写的现代、反应式框架&#xff0c;由许多抽象的层级组成。它包括一套丰富的布局、动画、绘制、手势UI组件及配套代码&#xff0c;以及更基础的异步、文件、…

参数引入和全局变量引入实现-目标和

LCR 102. 目标和 - 力扣&#xff08;LeetCode&#xff09; 分析题意&#xff0c;画出决策树&#xff0c;其他的思路都跟前面讲过的类似&#xff1a; 全局变量引入实现&#xff1a; 全局变量的引入&#xff0c;需要手动处理回溯&#xff1b; class Solution {int ret; //…

视频拉流推流技术梳理

概况 视频的整个流程主要分为推流和拉流 摄像头场景&#xff1a; 摄像头捕捉视频画面&#xff0c;推流到服务器&#xff0c;服务器分发到CDN&#xff0c; 客户端从CDN地址拉流&#xff0c;客户端进行播放 直播场景&#xff1a; 主播通过手机&#xff0c;电脑等客户端&…

前端爬虫+可视化Demo

爬虫简介 可以把互联网比做成一张 “大网”&#xff0c;爬虫就是在这张大网上不断爬取信息的程序。 爬虫是请求网站并提取数据的自动化程序。 省流&#xff1a;Demo实现前置知识&#xff1a; JS 基础Node 基础 &#xff08;1&#xff09;爬虫基本工作流程&#xff1a; 向…

RK3568平台 USB基础知识

一.现实工作中USB实际例子 现象&#xff1a;把USB设备比如Android手机接到PC 右下角弹出"发现android phone"跳出一个对话框&#xff0c;提示你安装驱动程序 问1&#xff1a;USB设备插到电脑上去&#xff0c;接触到的对方设备是什么&#xff1f; 答1&#xff1a;…

yum 和 rpm

rpm说明 rpm -qa &#xff1a;列出所有已安装的软件包 [roothub ~] rpm -qa geoipupdate-2.5.0-1.el7.x86_64 ncurses-base-5.9-14.20130511.el7_4.noarch libndp-1.2-9.el7.x86_64 libfastjson-0.99.4-3.el7.x86_64 。。。 rpm -qf FILENAME &#xff1a;查找提供 FILENAME…

SwiftUI之CoreData详解(一)

coreData 是一种数据持久化的方案&#xff0c;是对SQLite的一种封装。一说到这种桌面化的数据库&#xff0c;我就无比的怀念Foxbase|Foxpro, 多好的数据库产品&#xff0c;被微软扼杀了&#xff0c;相当年教大学生妹子们国家二级数据库时都是手把手教的&#xff0c;呃~~~&#…

wordpress模板官网

移民wordpress主题 移民代办wordpress主题&#xff0c;适合做海外移民咨询的代理公司搭建wordpress企业官方网站使用。 https://www.jianzhanpress.com/?p5130 夏令营wordpress主题 绿色夏令营wordpress主题&#xff0c;适合做夏令营或户外拓展的公司搭建wordpress官方网站…

【动态规划】第十一届蓝桥杯省赛第二场C++ C组《数字三角形》(c++)

1.题目描述 上图给出了一个数字三角形。 从三角形的顶部到底部有很多条不同的路径。 对于每条路径&#xff0c;把路径上面的数加起来可以得到一个和&#xff0c;你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。 …

绝地求生:小团团曝被判8年:地图语音包或将下架,公会和主播被一锅端

这两天大家都在讨论某鱼平台办卡抽奖的事情。这件事发生之后没多久&#xff0c;某鱼平台里面的大量主播在同一时间停播&#xff0c;闲游盒认为大家应该也懂的&#xff0c;这次停播就是因为这些主播也参与了办卡抽奖&#xff0c;都需要接受调查&#xff0c;在两个月左右的调查中…

【项目实践】如何发掘用户隐性需求推送PUSH

1.背景 对比业界广告推荐、触达成熟的平台&#xff0c;例如抖音&#xff0c;小红书&#xff0c;淘宝&#xff0c;知乎等&#xff0c;都已经站在巨量数据的基础之上&#xff0c;具备了 “用户意图分析” 的能力&#xff0c;可以分析出 “用户的隐性需求”&#xff0c;假设我们同…

Python学习日记(一:List、Tuple、dictionary)

前言&#xff1a; 最近想拓展一下自己的知识面&#xff0c;特来学习一下python这门语言&#xff0c;因为之前学习过C语言&#xff0c;目前学习起来Python还不是特别费劲&#xff0c;也由此感叹C语言不愧是最基础的语言。不多废话&#xff0c;进入正题 概述&#xff1a; Pytho…

典中典之西电A测-气压测控仿真系统

兄弟,如果你看到这篇,只能说明你A测也挂了,没办法,哥们太菜了,抄的太假过不了你电有些老师的慧眼 这坨&#x1f415;⑩我先吃为敬 环境搭建可以参考这个兄弟的博客 一、题目要求 实现功能&#xff1a;使用 Arduino UNO 微控制器&#xff0c;搭建一个 PC 上位机远程气压检测控…

动态规划:LeetCode第10题 正则表达式匹配

题目&#xff1a; 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c;是要涵盖 整个 字符串 s的&#xff0c;而不是部分字符串。 示例 1&#xff1a; …

C语言文件操作,linux文件操作,文件描述符,linux下一切皆文件,缓冲区,重定向

目录 C语言文件操作 如何打开文件以及打开文件方式 读写文件 关闭文件 Linux系统下的文件操作 open 宏标志位 write&#xff0c;read&#xff0c;close&#xff0c;lseek接口 什么是当前路径&#xff1f; linux下一切皆文件 文件描述符 文件描述符排序 C语言文件操…

【Linux从青铜到王者】进程信号

——————————————————————————————————————————— 信号入门 在了解信号之前有许多要理解的相关概念 我们可以先通过一个生活例子来初步认识一下信号 1.生活角度的信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来…

达梦、金仓、南大、瀚高、优炫:从社区建设看企业技术自信心

正文约950字&#xff0c;预计阅读时间2分钟 国产技术厂商在面对自身产品问题时&#xff0c;往往保持回避态度&#xff0c;不愿公之于众&#xff0c;主要原因有2方面&#xff1a; 1&#xff0c;产品技术层面问题较多&#xff0c;如某些根本性缺陷难以攻克&#xff0c;或问题发…