矩阵置零
给定一个 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]]
(上述题目来源于LeetCode)
首先,什么是原地算法呢?
百度的解释:
在计算机科学中,一个原地算法(in-place algorithm)是一种使用小的,固定数量的额外之空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉。不是原地算法有时候称为非原地(not-in-place)或不得其所(out-of-place)。
简单来说,就是在不新建大量额外空间的基础上对原数据进行操作。
解法一(使用标记数组1)
class Solution {
public void setZeroes(int[][] matrix) {
//先求出矩阵行数和列数
int m = matrix.length;
int n = matrix[0].length;
//设置两个数组,分别用来表示第几行是否为0和第几列是否为0
boolean []row = new boolean[m];
boolean []column = new boolean[n];
//遍历数组矩阵
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
//如果某个矩阵元素为0,其所在得行和列都标记为true
if(matrix[i][j] == 0){
row[i] = column[j] = true;
}
}
}
//再次遍历,通过上一次遍历的标记将相应元素赋值为0
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(row[i] == true || column[j] == true){
matrix[i][j] = 0;
}
}
}
}
}
解法二(使用标记数组2)
class Solution {
public void setZeroes(int[][] matrix) {
//先求出矩阵行数和列数
int m = matrix.length;
int n = matrix[0].length;
//设置两个数组,分别用来表示第几行是否为0和第几列是否为0
int []row = new int[m];
int []column = new int[n];
//遍历数组矩阵
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
//如果某个矩阵元素为0,其所在得行和列都标记为 1
if(matrix[i][j] == 0){
row[i] = column[j] = 1;
}
}
}
//再次遍历,通过上一次遍历的标记将相应元素赋值为0
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(row[i] == 1 || column[j] == 1){
matrix[i][j] = 0;
}
}
}
}
}
解法三(使用两个标记数组分别标记第一行和第一列)
class Solution {
public void setZeroes(int[][] matrix) {
//先求出矩阵行数和列数
int m = matrix.length;
int n = matrix[0].length;
//定义两个标记变量,分别用来标记第一行和第一列是否出现数字0
boolean row1 = false;
boolean column1 = false;
//循环第一行,若有0,标记变为true
for(int i = 0;i < n;i++){
if(matrix[0][i] == 0)
row1 = true;
}
//循环第一列,若有0,标记变为true
for(int j = 0;j < m;j++){
if(matrix[j][0] == 0)
column1 = true;
}
//后面的循环从第二行第二列开始,若某行某列有0,则将该行第1列和该列第1行置0
//即用其他行与列来更新第一行与第一列
for(int a = 1;a < m;a++){
for(int b = 1;b < n;b++){
if(matrix[a][b] == 0){
matrix[a][0] = matrix[0][b] = 0;
}
}
}
//再次循环遍历,将之前标记的某列第一行或者某行第一列为0的元素置为0
//即反过来用第一行与第一列去更新其他行列
for(int a = 1;a < m;a++){
for(int b = 1;b < n;b++){
if(matrix[a][0]==0 || matrix[0][b]==0){
matrix[a][b] = 0;
}
}
}
//使用标记变量来判定原本的第一行是否包含0,若包含,则将第一行元素置0
for(int i = 0;i < n;i++){
if(row1 == true){
matrix[0][i] = 0;
}
}
//使用标记变量来判定原本的第一列是否包含0,若包含,则将第一列元素置0
for(int j = 0;j < m;j++){
if(column1 == true){
matrix[j][0] = 0;
}
}
}
}