当前位置:网站首页>【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;
}
}
边栏推荐
猜你喜欢
Building a data ecology for feature engineering - Embrace the open source ecology, OpenMLDB fully opens up the MLOps ecological tool chain
微信小程序_开发工具的安装
2022DASCTF X SU 三月春季挑战赛 checkin ROPgadget进阶使用
解决npm warn config global `--global`, `--local` are deprecated. use `--location=global` instead.
Day 75
C语言-7月19日-指针的学习
C语言-7月18日-二维数组的学习
127.0.0.1 connection refused
Matplotlib找不到字体,打印乱码
【剑指offer系列】面试题日记(前期题)
随机推荐
Promise.race learning (judging the fastest execution of multiple promise objects)
星盟-pwn-babyheap
buuctf hacknote
swagger常用注释API @ApiModel、@ApiModelProperty的用法
IIC and SPI
C-动态内存管理
[Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development
Use the adb command to manage applications
自己动手写RISC-V的C编译器-01实现加减法
本地缓存cookie的使用
品优购项目实战笔记
C language implementation guess Numbers (with source code, can be directly run)
Compilation exception resolution
C语言-6月8日-给定一个字符数组‘i am a student’ 统计字符a的个数并进行输出
Day 81
Jetpack use exception problem collection
手把手导入企业项目(快速完成本地项目配置)
厂商推送平台-华为接入
JVM学习四:垃圾收集器与内存回收策略
SearchGuard configuration