【DFS/BFS】2023Q1A-开心消消乐

题目描述与示例

题目描述

给定一个 NM 列的二维矩阵,矩阵中每个位置的数字取值为 01,矩阵示例如:

1 1 0 0
0 0 0 1
0 0 1 1
1 1 1 1

现需要将矩阵中所有的 1 进行反转为 0,规则如下:

  1. 当点击一个 1 时,该 1 被反转为 0,同时相邻的上、下、左、右,以及左上、左下、右上、右下 8 个方向的 1 (如果存在 1)均会自动反转为 0;
  2. 进一步地,一个位置上的 1 被反转为 0 时,与其相邻的 8 个方向的 1 (如果存在 1)均会自动反转为 0

按照上述规则示例中的矩阵只最少需要点击 2 次后,所有均值 0 。请问,给定一个矩阵,最少需要点击几次后,所有数字均为 0

输入

第一行输入两个整数,分别表示矩阵的行数 N 和列数 M,取值范围均为 [1,100] 接下来 N 行表示矩阵的初始值,每行均为 M 个数,取值范围 [0,1]

输出

输出一个整数,表示最少需要点击的次数

示例一

输入

3 3
1 0 1
0 1 0
1 0 1

输出

1

说明

上述样例中,四个角上的 1 均在中间的 1 的相邻 8 个方向上,因此只需要点击一次即可。

示例二

输入

4 4
1 1 0 0
0 0 0 1
0 0 1 1
1 1 1 1

输出

2

解题思路

注意,本题和LC200. 岛屿数量几乎完全一致。唯一的区别在于,本题需要考虑八个方向而不是四个方向。

考虑八个方向时,我们需要定义方向数组为

DIRECTIONS = [(0,1), (1,0), (-1,0), (0,-1), (1,1), (1,-1), (-1,1), (-1,-1)]

剩余过程就是常规的DFS/BFS过程。

代码

解法一:BFS

# 题目:2023Q1A-开心消消乐
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:BFS
# 代码看不懂的地方,请直接在群上提问from collections import deque# 表示八个方向的数组
DIRECTIONS = [(0,1), (1,0), (-1,0), (0,-1), (1,1), (1,-1), (-1,1), (-1,-1)]# 输入行数、列数
n, m = map(int, input().split())
grid = list()
for i in range(n):row = input().split()grid.append(row)# 答案变量,用于记录连通块的个数
ans = 0
# 用于检查的二维矩阵
# 0表示没检查过,1表示检查过了
check_list = [[0] * m for _ in range(n)]# 最外层的大的双重循环,是用来找BFS的起始搜索位置的
for i in range(n):for j in range(m):# 找到一个1,并且这个1从未被搜索过:那么可以进行BFS的搜索# 1. 值是1        2. 没被搜索过if grid[i][j] == "1" and check_list[i][j] == 0:# BFS的过程q = deque()q.append([i, j])        # BFS的起始点check_list[i][j] = 1while(len(q) > 0):      # 当队列中还有元素时,持续地进行搜索qSize = len(q)for _ in range(qSize):# 弹出队头元素,为当前点x, y = q.popleft()for dx, dy in DIRECTIONS:nxt_x, nxt_y = x+dx, y+dy# 若下一个点要加入队列,应该满足以下三个条件:# 1.没有越界# 2.在grid中值为"1"# 3.尚未被检查过if 0 <= nxt_x < n and 0 <= nxt_y < m:       # 越界判断# 在grid中为"1",尚未被检查过if grid[nxt_x][nxt_y] == "1" and check_list[nxt_x][nxt_y] == 0:q.append([nxt_x, nxt_y])        # 入队check_list[nxt_x][nxt_y] = 1    # 标记为已检查过# BFS搜索完成,多了一个连通块ans += 1print(ans)

解法二:DFS

# 题目:2023Q1A-开心消消乐
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:DFS
# 代码看不懂的地方,请直接在群上提问# 表示八个方向的数组
DIRECTIONS = [(0,1), (1,0), (-1,0), (0,-1), (1,1), (1,-1), (-1,1), (-1,-1)]# 输入行数、列数
n, m = map(int, input().split())
grid = list()
for i in range(n):row = input().split()grid.append(row)# 答案变量,用于记录连通块的个数
ans = 0
# 用于检查的二维矩阵
# 0表示没检查过,1表示检查过了
check_list = [[0] * m for _ in range(n)]# dfs递归函数
def dfs(check_list, x, y):# 将点(x, y)标记为已检查过check_list[x][y] = 1for dx, dy in DIRECTIONS:nxt_x, nxt_y = x + dx, y + dy# 若下一个点继续进行dfs,应该满足以下三个条件:# 1.没有越界# 2.在grid中值为"1"# 3.尚未被检查过if 0 <= nxt_x < n and 0 <= nxt_y < m:       # 越界判断# 在grid中为"1",尚未被检查过# 可以进行dfsif grid[nxt_x][nxt_y] == "1" and check_list[nxt_x][nxt_y] == 0:dfs(check_list, nxt_x, nxt_y)# 最外层的大的双重循环,是用来找DFS的起始搜索位置的
for i in range(n):for j in range(m):# 找到一个"1",并且这个"1"从未被搜索过:那么可以进行DFS的搜索# 1. 值得是"1"       2. 没被搜索过if grid[i][j] == "1" and check_list[i][j] == 0:dfs(check_list, i, j)# DFS搜索完成,多了一个连通块ans += 1print(ans)

时空复杂度

时间复杂度:O(MN)

空间复杂度:O(MN)

华为OD算法冲刺训练

  • 华为OD算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 30+天陪伴式学习,20+直播课时,300+动画图解视频,200+LeetCode经典题,100+华为OD真题,还有简历修改与模拟面试将为你解锁

  • 可查看链接 OD算法冲刺训练课程表 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 sheepvipvip了解更多

20天拿下华为OD笔试之【DFS/BFS】2023Q1A-开心消消乐【闭着眼睛学数理化】全网注释最详细分类最全的华为OD真题题解相关推荐

  1. 【限时免费】20天拿下华为OD笔试之【DFS/BFS】2023B-寻找最大价值的矿堆【闭着眼睛学数理化】全网注释最详细分类最全的华为OD真题题解

    [DFS/BFS]2023B-寻找最大价值的矿堆 题目描述与示例 给你一个由 '0'(空地).'1'(银矿).'2'(金矿)组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成.超出地图范围可以认 ...

  2. 笔试真题解析 | 4.15携程实习笔试三道编程题

    恭喜发现宝藏!搜索公众号[TechGuide]回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经. 作者@TechGuide[全网同名] 订阅专栏[进阶版]2023最新大厂笔试真题 & 题解, ...

  3. 【2023华为OD笔试必会25题--C语言版】目录

    本专栏收录了华为OD 2022 Q4和2023Q1笔试题目,100分类别中的出现频率最高(至少出现100次)的25道,每篇文章包括题目和我亲自编写并在Visual Studio中运行成功的C语言代码. ...

  4. 华为OD笔试202010OD笔试华为OD第二题最长的非递减连续子序列的长度

    华为OD笔试202010OD笔试华为OD第二题最长的非递减连续子序列的长度要连续的数字序列的最长的长度 直接看输入输出 输入 abc2234019A334bc 输出 4 解释:输入一个字符串,只包含字 ...

  5. 华为机试(JAVA)真题Od【A卷+B卷】

    各语言题库: [Python+JS+Java合集][超值优惠]:Py/JS/Java合集 [Python]:Python真题题库 [JavaScript]:JavaScript真题题库 [Java]: ...

  6. 华为机试(Python)真题Od【A卷+B卷】

    各语言题库: [Python+JS+Java合集][超值优惠]:Py/JS/Java合集 [Python]:Python真题题库 [JavaScript]:JavaScript真题题库 [Java]: ...

  7. 华为OD机试真题2023(JavaScript)

    华为机试题库已由2022版换为2023版   华为机试有三道题目,第一道和第二道属于简单或中等题,分值为100分,第三道为中等或困难题,分值为200分.总分为400分,150分钟考试时间.之前通过为1 ...

  8. 【华为OD机试】-2023(A+B卷)真题【C++,JAVA,Python】

    考点分类:华为OD机试真题(2023)-考点分类 近期考题:华为OD机试 真题2023 Q1 (A卷) c++/python/java专栏:华为OD机试(Python,Java,C++)2023(A+ ...

  9. 2023华为OD面试手撕代码真题

    很多小伙伴后台私信我,让我出一些面试中的手撕代码题. 一般面试的时候每一轮技术面都会出一到两个手撕代码题,这些题的特点就是,非常短小,易于理解.不可能会再出阅读理解一样的机试题的.但是这些题目也非常注 ...

最新文章

  1. R语言使用psych包的fa函数对指定数据集进行因子分析(输入数据为相关性矩阵)、使用rotate参数指定进行斜交旋转提取因子、使用nfactors参数指定抽取的因子个数、fa函数因子分析结果解读
  2. macbook下载苹果版Photoshop cc2019 for mac
  3. 使用keepalived监控tomcat 达到双机热备
  4. Flume日志采集,avro采集,以及通过参数控制下沉到hdfs的文件大小,时间等控制
  5. HDU 1492 The number of divisors(约数) about Humble Numbers(数论,简单约数)
  6. mysql java文件导入导出_MySQL文件导出和导入
  7. 多线程编程学习笔记——使用并发集合(三)
  8. 20135213 20135231 信息安全系统设计基础课程第三次实验报告
  9. 参加2013中国大数据技术大会(BDTC2013)
  10. 数据卡片_手把手教你构建企业实时数据大屏
  11. 使用 guard 的正确姿势
  12. WCF读书笔记(1)
  13. F - XOR Equation CodeForces - 635C (数学)
  14. 易语言c编译,易语言命令行编译工具免费版下载_易语言命令行编译工具最新版下载_3DM软件...
  15. centos设置自动开关机
  16. 计算机c盘扩容不用软件,电脑分区c盘扩容,这个方法超级简单!
  17. 利用Matlab实现单像空间后方交会
  18. 以防遗忘001_通过斜率求垂直线段的端点,附Unity(UI image)画线
  19. C语言提取字符对应的ASCAl,ascall码对照表(ASCII码表)
  20. 基于Unity3D的相机功能的实现(六)—— 上帝视角(王者荣耀视角)

热门文章

  1. 我常去逛的iOS干货文章、blog等
  2. 微信小程序获取经纬度有偏差的解决方案,
  3. 黑猴子的家:TortoiseSVN 客户端安装
  4. msf与cs互传shell
  5. 交通期刊排名(2021.6更新)
  6. SpringBoot前后端分离参数传递方式总结
  7. 改变你的人生的32句经典句子
  8. 瑞星预警:Vista出现首个重大安全漏洞
  9. “JSON parse error: Unexpected character (‘1‘ (code 49))的解决方式
  10. 面向对象(类和对象、重载、构造方法、this关键字)