六、矩阵问题

73、矩阵置零(中等)

题目描述

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。

示例 1:

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

示例 2:

输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

提示:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -231 <= matrix[i][j] <= 231 - 1

进阶:

  • 一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗?

题目思路

对于这道题,要求将一个矩阵中含有0的位置,该行和该列都设置为0。

这道题有点类似于炸弹人的游戏机制,炸弹将一行和一列全部炸裂了。
说到这道题,如果没有空间的限制,很容易实现。

  • 如果是O(mn),非常简单,新开辟一个新的矩阵即可。
  • 如果是O(m+n),也不是很困难,我们利用额外的空间记录对应的行和列是否为0即可。

而如果是常量的空间复杂度,就较为麻烦了,这就需要我们利用现有的空间来记录信息——即使用当前的数组来记录信息。

因此这里,我们的思路是使用当前矩阵的第一行和第一列来记录对应的行和列是否应该为0

不过这里有一个问题:

  • 如果第一行和第一列本身就有0,那么这样的记录就会造成 “污染”,因此,这里我们需要对第一行和第一列做单独的判断。

在算法流程上:

  • 判断第一行和第一列是否应该为0;
  • (1, 1)开始,自上而下、自左向右判断元素num[i][j]是否为0——如果为0,就设置num[i][0]num[0][j]为0;
  • 再次遍历,根据对应第一行和第一列元素的值,对当前的值进行赋值——如果标记为0,则置为0;
  • 最后,根据第一步的判断结果,对第一行和第一列更新数据;

算法代码

1、O(m+n)

class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""zero_row, zero_col = [], []m, n = len(matrix), len(matrix[0])for i in range(m):for j in range(n):if matrix[i][j] == 0:zero_row.append(i)zero_col.append(j)for r in zero_row:for j in range(n):matrix[r][j] = 0for c in zero_col:for i in range(m):matrix[i][c] = 0

2、常量空间

class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""is_first_row_zero, is_first_col_zero = False, Falsem, n = len(matrix), len(matrix[0])for i in range(m):if matrix[i][0] == 0:is_first_col_zero = Truebreakfor j in range(n):if matrix[0][j] == 0:is_first_row_zero = Truebreakfor i in range(1, m):for j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = 0matrix[0][j] = 0for i in range(1, m):for j in range(1, n):if matrix[i][0] == 0 or matrix[0][j] == 0:matrix[i][j] = 0if is_first_col_zero:for i in range(m):matrix[i][0] = 0if is_first_row_zero:for j in range(n):matrix[0][j] = 0

54、螺旋矩阵(中等)

题目描述

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

题目思路

对于这道题,要求我们按照顺时针的方向对矩阵进行遍历,最后转化为一维数组。
在进行数组展开时,我们可以看到顺序是:

  • 向右->向下->向左->向上

如果直接去模拟,整个过程较为繁琐,需要定义每个方向要走多少步等。
这里,我们通过不断重新定义矩阵上下左右边界的方法,来实现循环遍历。

算法具体步骤:

  • 初始化矩阵的上下左右边界;
  • 在上边界(即第一行)从最左移动到最右,此时第一行遍历完后相当于已经用过了,因此可以直接从图中删去,即重新定义上边界(top+1);
    • 若重新定义上边界后,上、下边界交错(top > bottom),说明此时矩阵遍历结束,直接跳出循环,返回结果即可;
    • 若上下不交错,则继续在最右边界处,从最上遍历到最下,逻辑同理;
  • 不断循环上述步骤,直到其中某两条边界交错,跳出循环,返回结果;

算法代码

class Solution:def spiralOrder(self, matrix: List[List[int]]) -> List[int]:res = []# 定义矩阵上下边界top, bottom = 0, len(matrix) - 1# 定义矩阵左右边界left, right = 0, len(matrix[0]) - 1while True:# 在上边界,从最左遍历到最右for i in range(left, right+1):res.append(matrix[top][i])# 重新设置上边界,如果上边界大于下边界,说明遍历完成,下同top += 1if top > bottom:break# 在右边界,从最上遍历到最下for i in range(top, bottom+1):res.append(matrix[i][right])right -= 1if right < left:break# 在下边界,从最右遍历到最左for i in range(right, left-1, -1):res.append(matrix[bottom][i])bottom -= 1if bottom < top:break# 在左边界,从最下遍历到最上for i in range(bottom, top-1, -1):res.append(matrix[i][left])left += 1if left > right:breakreturn res

48、旋转图像(中等)

题目描述

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

题目思路

对于这道题,本质上是要求我们将一个二维n*n矩阵顺时针旋转90度。

如果我们可以使用额外空间,比较简单直接:

  • 对于矩阵中第i行第j个元素,旋转后,会出现在倒数第i列的第j个位置:
    • matrix_new[j][n - i - 1] = matrix[i][j]

但题目这里不允许使用额外的空间,因此这里我们需要在原二维矩阵进行操作,这里可以直接通过翻转得到。

  • 顺时针旋转:
    • 先通过水平轴翻转,再根据主对角线翻转;
  • 逆时针旋转:
    • 先通过垂直轴翻转, 再根据主对角线旋转;

顺时针:

 1 2 3     7 8 9     7 4 14 5 6  => 4 5 6  => 8 5 27 8 9     1 2 3     9 6 3

逆时针:

 1 2 3     3 2 1     3 6 94 5 6  => 6 5 4  => 2 5 87 8 9     9 8 7     1 4 7

以顺时针为例,之所以能够通过两次翻转得到,是由于:
1、水平轴翻转:

  • matrix[row][col] => matrix[n-row-1][col]

2、主对角线翻转:

  • matrix[n-row-1][col] => matrix[col][n-row-1]

因此最终可以得到:

  • matrix_new[j][n - i - 1] = matrix[i][j]

算法代码

class Solution:def rotate(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""matrix.reverse()for i in range(len(matrix)):for j in range(i+1, len(matrix)):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

附带逆时针:

class Solution48:def rotate(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""matrix = [list(reversed(x)) for x in matrix]for i in range(len(matrix)):for j in range(i+1, len(matrix)):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

240、搜索二维矩阵 II(中等)

题目描述

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例 1:

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

示例 2:

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109 <= matrix[i][j] <= 109
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109 <= target <= 109

题目思路

对于这道题,要求我们在一个二维数组中找到目标值。

首先,我们可以直接使用暴力搜索的

不过在这道题中该二维数组具备:

  • 每行的元素从左到右升序排列;
  • 每列的元素从上到下升序排列;

因此,我们可以从矩阵的右上角(0, n-1)进行从右向左、从上到下进行查找。

这是由于如果我们从左上角开始,如果matrix[x][y]小于target,那么下一个查找的数字既有可能在右边、也有可能在下边,查找起来就很麻烦。

然而如果我们从右上角开始查找:

  • 如果matrix[x][y] == target,说明查找完成;
  • 如果matrix[x][y] > target,由于每一列的元素都是升序排列的,那么在当前的搜索矩阵中,所有位于第 y 列的元素都是严格大于 target 的,因此我们可以将它们全部忽略,即将 y-1
  • 如果matrix[x][y] < target,由于每一行的元素都是升序排列的,那么在当前的搜索矩阵中,所有位于第 x 行的元素都是严格小于 target 的,因此我们可以将它们全部忽略,即将 x+1

在搜索的过程中,如果我们超出了矩阵的边界,那么说明矩阵中不存在 target

算法代码

class Solution:def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:m, n = len(matrix), len(matrix[0])x, y = 0, n-1while x < m and y >= 0:if matrix[x][y] == target:return Trueelif matrix[x][y] > target:y -= 1else:x += 1return False

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

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

相关文章

应用案例 | Softing echocollect e网关助力汽车零部件制造商构建企业数据库,提升生产效率和质量

为了提高生产质量和效率&#xff0c;某知名汽车零部件制造商采用了Softing echocollect e多协议数据采集网关——从机器和设备中获取相关数据&#xff0c;并直接将数据存储在中央SQL数据库系统中用于分析处理&#xff0c;从而实现了持续监控和生产过程的改进。 一 背景 该企业…

【国家机关办公建筑 大型公共建筑的能耗监测、集中统一管理】安科瑞能耗监测系统整体解决方案

背景 为全面推进大型公建节能管理工作&#xff0c;需建立大型公建节能监管体系&#xff0c;逐步建立起全国联网的大型公建能耗监测平台&#xff0c;在大型公建安装分项计量装置&#xff0c;通过远程传输等手段及时采集分析能耗数据&#xff0c;实现对大型公建的实时动态监测、汇…

Docker数据卷的挂载

目录 1 概念 2 常用命令 3 操作步骤(主要讲在创建容器时的挂载) 3.1 挂载在默认目录 3.2 挂载在自定义目录 4 附加内容(查看容器的挂载情况) 1 概念 数据卷&#xff08;volume&#xff09;是一个虚拟目录&#xff0c;是容器内目录与宿主机目录之间映射的桥梁。这样容器内…

微服务day05-Gateway网关

Gateway网关 为了防止微服务能被任何身份的人访问&#xff0c;需要对访问微服务的人做身份认证和权限校验。网关的功能就是对访问用户进行身份认证和权限校验。网关具有3种功能&#xff1a; 身份验证和权限校验&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否…

git 如何将多个提交点合并为一个提交点 commit

文章目录 核心命令详细使用模式总结示例 核心命令 git merge branch2 是将分支branch2的提交点合并到本地当前分支。 而在执行这条命令的时候&#xff0c;加一个选项--squash就表示在合并的时候将多个提交点合并为一个提交点。 git merge --squash branch2 先看squash单词的意…

React Hooks 完全指南:无类组件革命

目录 ​编辑 前言 Hooks的前世 函数组件 类组件 状态和生命周期的管理 Hooks用途以及相应代码 状态管理 用于生命周期管理和副作用操作的 Hooks 用于上下文管理的 Hooks 其他用途的 Hooks 前言 React Hooks 是在 React 16.8 版本中引入的一个非常强大的新特性&…

建筑外窗遮阳系数测试的太阳光模拟器

太阳光模拟器是一种用于测试建筑外窗遮阳系数的高科技设备。它能够模拟太阳光照射房屋的情景&#xff0c;帮助建筑师和设计师更好地了解建筑外窗的遮阳性能&#xff0c;从而提高建筑的能源效率和舒适度。 这种模拟器的工作原理非常简单&#xff0c;它通过使用高亮度的光源和精…

scrapy 爬虫:多线程爬取去微博热搜排行榜数据信息,进入详情页面拿取第一条微博信息,保存到本地text文件、保存到excel

如果想要保存到excel中可以看我的这个爬虫 使用Scrapy 框架开启多进程爬取贝壳网数据保存到excel文件中&#xff0c;包括分页数据、详情页数据&#xff0c;新手保护期快来看&#xff01;&#xff01;仅供学习参考&#xff0c;别乱搞_爬取贝壳成交数据c端用户登录-CSDN博客 最终…

Bee Mobile组件库重磅升级

Bee Mobile组件库重磅升级&#xff01; 丰富强大的组件移动预览快速上手create-bee-mobile Bee Mobile组件库重磅升级&#xff01; Bee Mobile组件库最新 v1.0.0 版本&#xff0c;支持最新的 React v18。 主页&#xff1a;Bee Mobile 丰富强大的组件 一共拥有50多个组件&…

Java面向对象总结 ( 知识点 | 代码详解 )

类和对象 什么是类&#xff1f; ● 概念&#xff1a;具有相同特征&#xff08;同一类&#xff09;事物的抽象描述&#xff0c;如人类&#xff0c;车类&#xff0c;学生类等。 类的结构&#xff1a; ● 变量: 事物属性的描述(名词) ● 方法: 事物的行为&#xff08;可以做…

基于Flask的宠物领养系统的设计与实现

基于Flask的宠物领养系统的设计与实现 涉及技术&#xff1a;python3.10flaskmysql8.0 系统分为普通用户和管理员两种角色&#xff0c;普通用户可以浏览搜索宠物&#xff0c;申请领养宠物&#xff1b;管理员可以分布宠物信息&#xff0c;管理系统等。 采用ORM模型创建数据&am…

QT----云服务器部署Mysql,Navicat连接1698 -Access denied for user ‘root‘@‘‘

阿里云有活动&#xff0c;白嫖了一年的新加坡轻量级服务器&#xff0c;有点卡&#xff0c;有时候要开梯子 白嫖300元优惠券 目录 1 安装启动Mysql服务2 更改连接权限2.1 Navicat连接报错1698 -Access denied for user root 3 qt连接云服务器数据库 1 安装启动Mysql服务 我使用…

f5——>字符串三角

暴力破解&#xff0c;双层循环&#xff0c;注意复制到新列表用append&#xff0c;这样更不容易出错 格式还是“”.join(str)

Grid网格布局的基本使用

文章目录 什么是网格布局属性display 属性grid-row-gap 属性&#xff0c; grid-column-gap 属性&#xff0c; grid-gap 属性grid-template-areas 属性grid-auto-flow 属性justify-items 属性 &#xff0c; align-items 属性&#xff0c; place-items 属性justify-content 属性 …

Java高频面试之集合篇

Java 中常用的容器有哪些&#xff1f; ArrayList 和 LinkedList 的区别&#xff1f; ArrayList 是基于数组实现的,LinkedList 是基于链表实现的. ArrayList实现了RandomAccess接口,可基于下标访问. LinkedList 实现了Deque /dek/,可以当做双端队列使用. 插入效率对比 如果从头部…

Unity的滑动控制相机跟随和第三人称视角三

Unity的相机跟随和第三人称视角三 第三人称相机优化介绍讲解拖动事件相机逻辑人物移动逻辑总结 第三人称相机优化 Unity第三人称相机视角一 Unity第三人称相机视角二 介绍 之前相机视角讲过了两篇文章了&#xff0c;但是都是自动旋转视角&#xff0c;今天来了新需求&#xf…

支部管理系统微信小程序(管理端+用户端)flask+vue+mysql+微信小程序

系统架构如图所示 高校D支部管理系统 由web端和微信小程序端组成&#xff0c;由web端负责管理&#xff0c;能够收缴费用、发布信息、发布问卷、发布通知等功能 部分功能页面如图所示 微信小程序端 包含所有源码和远程部署&#xff0c;可作为毕设课设

Java 数据结构之链表

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA null || headB null) return null;ListNode pA headA, pB headB;while (pA ! pB) {pA pA null ? headB : pA.next;pB pB null ? headA : pB.next;}return pA;} public ListNode rev…

数据库系列之:什么是 SAP HANA?

数据库系列之&#xff1a;什么是 SAP HANA&#xff1f; 一、什么是 SAP HANA&#xff1f;二、什么是内存数据库&#xff1f;三、SAP HANA 有多快&#xff1f;四、SAP HANA 的十大优势五、SAP HANA 架构六、数据库设计七、数据库管理八、应用开发九、高级分析十、数据虚拟化 一、…

1-安装rabbitmq

rabbitmq官网&#xff1a; https://www.rabbitmq.com/docs/download 本机环境&#xff1a;mac&#xff0c;使用orbstack提供的docker 使用docker部署rabbitmq docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.13-management 然后报错&#xf…