赞
踩
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
首先这题最重要的一点,是如何处理置0后,不会影响后续遍历结果。也就是要避免在某次操作中我将a[i][j]置0,而之后我遍历到a[i][j]元素时,其原本的值丢失,导致最后数组所有元素都是0。
如果允许O(mn)空间:直接新开一个m*n的数组,扫描原数组,置0操作在新数组中执行,这样就不必担心置0后续遍历的结果。
如果允许O(m+n)空间。那么可以分别开两个m,n长度的数组,分别记录这一行/这一列中有没有0出现,有则置0,最后根据这两个数组哪些元素为0即可判断哪些行以及哪些列需要置0。(用0来做记录原因是我们不知道数组中存在哪些值,唯有使用0这个特殊值)
而如果只允许常数空间,我们就需要对上面O(m+n)的解法进一步优化,我们直接使用原数组的第一行和第一列元素记录当前行或者当前列中除本身以外是否存在0,如果存在0,则将首元素置0,如用a[2][0]记录第3行中除了a[2][0]以外的元素中是否存在0,如果后者中出现0了,那么我们将a[2][0]置0。
但是这样有一个问题:我如何处理第一行或者第一列中本身就有0存在?因此我们又需要额外两个变量firstRowIsZero,firstColIsZero判断第一行以及第一列本身是否存在0。
这样我们先对除了第一行第一列以外的元素进行置0,在根据上面两个变量来判断是否对第一行第一列置0
class Solution {
//用第一行的元素表示每一列是否存在0,第一列的元素表示每一行是否存在0
//同时要处理第一行第一列本身存在0的情况
public void setZeroes(int[][] matrix) {
if(matrix.length == 0){
return;
}
boolean firstRowIsZero = false,firstColIsZero = false;
for(int i =0;i<matrix.length;i++){
for(int j=0;j<matrix[0].length;j++){
if(i!=0 && j!=0 && matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}else if(matrix[i][j]==0){
firstRowIsZero = i==0? true:firstRowIsZero;
firstColIsZero = j==0? true:firstColIsZero;
}
}
}
for(int i=1;i<matrix.length;i++){
for(int j=1;j<matrix[0].length;j++){
if(matrix[0][j]==0 || matrix[i][0] == 0){
matrix[i][j]=0;
}
}
}
//第一列含0
if(firstColIsZero){
for(int i=0;i<matrix.length;i++){
matrix[i][0] = 0;
}
}
//第一行含0
if(firstRowIsZero){
for(int j=0;j<matrix[0].length;j++){
matrix[0][j] = 0;
}
}
}
}
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。