题目:给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用原地算法。
这是一道有关矩阵转换的题目,输入一个二维数组,要求写一段程序修改这个二维数组后输出。
终于遇到一道比较简单的题目了,看起来不涉及任何复杂的算法。(目前最没新鲜感的一道题
)
直接看案例的输入输出: 输入的二维数组中,二行二列是0,在输出的二维数组中,第二行内的所有元素全是0,第一、三行内的第二个元素是0,其他元素保持原有的数字不变。
所以可以得知:
输入的二维数组内第i个元素内的第j个元素为0(matrix[i][j]==0),那么
输出时将此数组的第i个元素内的每个元素都赋值为0(matrix[i][0]=0,matrix[i][1]=0,matrix[i][2]=0...matrix[i][n]=0),
然后对于该数组内的其他元素,每个元素内的第j个元素赋值为0(matrix[0][j]=0,matrix[1][j]=0,matrix[2][j]=0...matrix[n][j]=0).
根据这个思路:
1.先记录下matrix数组中行和列的长度,将输入的二维数组复制一份一模一样的浅拷贝用于做修改,就叫做narray
int rows = matrix.length;
int cols = matrix[0].length;
int[][] narray = new int[rows][cols];
// 遍历matrix的每一行和每一列,并将元素复制到narray
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
narray[i][j] = matrix[i][j]; // 浅拷贝元素
}
}
复制
2. 遍历这个matrix的行和列,如果发现第i行j列是0,就将narray的i行内所有元素赋值为0,再将每一行的第j个元素赋值为0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] == 0) {
System.out.println(Integer.toString(i)+Integer.toString(j));
for (int k = 0; k < matrix[0].length; k++) {
narray[i][k] = 0;
}
for (int k = 0; k < matrix.length; k++) {
narray[k][j] = 0;
}
}
}
}
复制
3.让matrix等于narray,打印一下看看
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = narray[i][j]; // 浅拷贝元素
}
}
Arrays.stream(matrix).map(Arrays::toString).forEach(System.out::println);
复制
输入:int[][] matrix = new int[][]{{0,1,2,0},{3,4,5,2},{1,3,1,5}};
输出:
[0, 0, 0, 0]
[0, 4, 5, 0]
[0, 3, 1, 0]
本来有点担心用了这么多For循环,可能右会被卡复杂度,结果直接提交成功了。。。
然后看官方答案,官方答案要巧妙一点,创建了两个标记数组,分别记录matrix矩阵的0在第几行第几列。
int m = matrix.length, n = matrix[0].length;
boolean[] row = new boolean[m];
boolean[] col = new boolean[n];
复制
如果有0在第i行第j列,那么row[i] = true,col[j]=true
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
复制
然后我们将此matrix矩阵的i行和j列的所有元素都赋值为0。
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (row[i] || col[j]) {
matrix[i][j] = 0;
}
}
}