当前位置:网站首页>【LeetCode-73】矩阵置零
【LeetCode-73】矩阵置零
2022-08-11 05:30:00 【Ring*】
1.3 矩阵置零【73】
1.3.1 题目描述
给定一个 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
1.3.2 方法一:
思路和算法
我们可以用两个标记数组分别记录每一行和每一列是否有零出现。
具体地,我们首先遍历该数组一次,如果某个元素为 0,那么就将该元素所在的行和列所对应标记数组的位置置为 true。最后我们再次遍历该数组,用标记数组更新原数组即可。
代码
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean[] row = new boolean[m];
boolean[] col = new boolean[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (row[i] || col[j]) {
matrix[i][j] = 0;
}
}
}
}
}
复杂度分析
- 时间复杂度:O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。我们至多只需要遍历该矩阵两次。
- 空间复杂度:O(m+n),其中 m 是矩阵的行数,n 是矩阵的列数。我们需要分别记录每一行或每一列是否有零出现。
1.3.3 方法二:使用两个标记变量
思路和算法
我们可以用矩阵的第一行和第一列代替方法一中的两个标记数组,以达到 O(1) 的额外空间。但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 0。因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含 0。
在实际代码中,我们首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列,然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean flagCol0 = false, flagRow0 = false;
for (int i = 0; i < m; i++) {
// 记录第一列是否有0
if (matrix[i][0] == 0) {
flagCol0 = true;
}
}
for (int j = 0; j < n; j++) {
// 记录第一行是否有0
if (matrix[0][j] == 0) {
flagRow0 = true;
}
}
for (int i = 1; i < m; i++) {
// 扫描除了第一行第一列其他是否有0,有的话记录在第一行第一列
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
// 通过第一行第一列是否有0将整行整列置0
matrix[i][j] = 0;
}
}
}
if (flagCol0) {
// 之前的第一列有0,则将整列置0
for (int i = 0; i < m; i++) {
matrix[i][0] = 0;
}
}
if (flagRow0) {
// 之前的第一行有0,则将整行置0
for (int j = 0; j < n; j++) {
matrix[0][j] = 0;
}
}
}
}
复杂度分析
- 时间复杂度:O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。我们至多只需要遍历该矩阵两次。
- 空间复杂度:O(1)。我们只需要常数空间存储若干变量。
1.3.4 方法三:使用一个标记变量
思路和算法
我们可以对方法二进一步优化,只使用一个标记变量记录第一列是否原本存在 0。这样,第一列的第一个元素即可以标记第一行是否出现 0。但为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素。
代码
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean flagCol0 = false;
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
flagCol0 = true;
}
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
for (int i = m - 1; i >= 0; i--) {
for (int j = 1; j < n; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
if (flagCol0) {
matrix[i][0] = 0;
}
}
}
}
复杂度分析
- 时间复杂度:O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。我们至多只需要遍历该矩阵两次。
- 空间复杂度:O(1)。我们只需要常数空间存储若干变量。
1.3.5 my answer—记录0的位置
class Solution {
public void setZeroes(int[][] matrix) {
List<coordinates> list = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if(matrix[i][j]==0){
list.add(new coordinates(i,j));
}
}
}
for (coordinates coordinates : list) {
int x = coordinates.x;
int y = coordinates.y;
for (int j = 0; j < matrix[x].length; j++) {
matrix[x][j] = 0;
}
for (int i = 0; i < matrix.length; i++) {
matrix[i][y] = 0;
}
}
}
}
class coordinates{
int x;
int y;
public coordinates(int x, int y) {
this.x = x;
this.y = y;
}
}
边栏推荐
- IndexError: index 9 is out of bounds for axis 0 with size 9;数组下标溢出问题
- 8-byte standard request parsing during USB enumeration
- Day 77
- 【LeetCode-69】x的平方根
- Getting Started with JNI
- Promise.race learning (judging the fastest execution of multiple promise objects)
- The Summer of Open Source 2022 is coming | Welcome to sign up for the OpenMLDB community project~
- The mount command - mounted read-only, solution
- 虚拟机更改IP地址
- C语言-7月19日-指针的学习
猜你喜欢
C语言-7月31日-指针的总结以及typedef关键字
轻松理解进程与线程
JVM tuning and finishing
无效的修订:3.18.1-g262b901-dirty
经纬度求距离
JS进阶网页特效(pink老师笔记)
【LeetCode-69】x的平方根
将一个excel文件中多个sheet页“拆分“成多个“独立“excel文件
ARM assembly instruction ADR and LDR
连接数据库时出现WARN: Establishing SSL connection without server‘s identity verification is not recommended.
随机推荐
mongoose连接mongodb不错,显示encoding没有定义
C语言-7月31日-指针的总结以及typedef关键字
【LeetCode-34】在排序数组中查找元素的第一个和最后一个位置
js 学习进阶(事件高级 pink老师教学笔记)
Jetpack's dataBinding
Jetpack使用异常问题集锦
Day 69
使用adb命令管理应用
C语言预处理
2021-09-11 C language variables and memory allocation
自己动手写RISC-V的C编译器-00环境配置
第六届蓝帽杯 EscapeShellcode
Matplotlib找不到字体,打印乱码
Day 75
C-自定义类型(结构体、枚举、联合)
Thesis unscramble TransFG: A Transformer Architecture for Fine - grained Recognition
Asis2016 books null off by one
swagger常用注释API @ApiModel、@ApiModelProperty的用法
Some formulas for system performance and concurrency
C-8月1日-递归与动态内存管理