这是一个面试问题:在一个大小为 mxn 的二维数组中,对于每个值为 0 的元素,将该元素所在的整个行和列设置为零,其余元素保持不变。
我可以想到的方法是遍历数组中的每个元素,每次遇到零时,我用零标记整个行和列。但这是幼稚的,请提出任何改进建议。
这是一个面试问题:在一个大小为 mxn 的二维数组中,对于每个值为 0 的元素,将该元素所在的整个行和列设置为零,其余元素保持不变。
我可以想到的方法是遍历数组中的每个元素,每次遇到零时,我用零标记整个行和列。但这是幼稚的,请提出任何改进建议。
如果允许额外的空间。只需维护两个标志数组。
一个代表行,另一个代表列。所有默认值设置为 1。
扫描您的原始矩阵,假设您在 x 行和 y 列找到一个 0。只需设置 row[x] = 0; 和列[y] = 0;
然后再次扫描你的矩阵
for ( int i = 0; i < height; ++i )
for ( int j = 0; j < width; ++j )
M[i][j] = M[i][j] * row[i] * column[j];
然后你得到你的矩阵 M 改变
你的算法的复杂性是二次的。如果整个矩阵最初全为零,您将擦除每一列n_rows
时间和每一行n_columns
时间。
更好的方法是维护布尔数组的大小m
,并n
指示哪些行和列需要归零。遍历矩阵的元素,适当地填充布尔数组。完成后,遍历布尔数组并根据您在其中找到的值进行零填充。这样,每个元素最多清零两次。
如果您在进行过程中归零,您将在找到第一个之后清除每一行和每一列。只需在清零行和列之前找到并记录所有零。或者,创建二维数组的副本并修改第二个,同时查看第一个以供参考。
允许额外的空间?如果是这样,给定 mxn 矩阵,我们为行维护两个大小为 m 的位图,以指示何时应将行归零,对于列也类似。位图可以很容易地检查 O(1) 中是否已经设置了行或列。
Pass 1:优化矩阵的迭代,在遍历矩阵的元素寻找零的同时,当我们发现零是位置 (i,j) 时,我们可以设置两个位图中的对应位并停止迭代该行进一步的元素。(毕竟我们将整行和整列归零)。
第 2 步:现在我们有了两个位图,循环遍历它们,将行和列归零。如果您想在将行中的元素归零时非常优化(如果归零是一项代价高昂的操作),则可以跳过相应的列位是否已设置,在遍历列时最终归零。
编辑:您可以一次性完成,只需为列单独设置一个位图,如果找到零则遍历矩阵,将整行和列设置为零,设置列位图位置,然后继续下一行. 在迭代后续行时跳过设置了位的列
package helloWorld;
import java.util.HashMap;
import java.util.Map;
public class Solution {
public static int[][] myFunction(int[][] matrix) {
// find all rows and columns that contains zeros
// keep their indexes in hashMap
// loop over the matrix and check if you have row and column in your
// hashmap if yes make them zero, and also mark the row/column as
// already zeroed
Map<String, Boolean> map = new HashMap<String, Boolean>();
int length = matrix[0].length;
int heigth = matrix.length;
for (int i = 0; i < heigth; i++) {
for (int j = 0; j < length; j++) {
if (matrix[i][j] == 0) {
// mark and keep Row in Map
if (!map.containsKey("R" + i)) {
map.put("R" + i, false);
}
// mark and keep column in Map
if (!map.containsKey("C" + j)) {
map.put("C" + j, false);
}
}
}
}
for (int i = 0; i < length; i++) {
//check if row need to be zeroed and if yes zero it and Mark it
//as done
if (map.containsKey("R" + i) && !map.get("R" + i)) {
for (int j = 0; j < length; j++) {
matrix[i][j] = 0;
}
map.put("R" + i, true);
}
//check if column need to be zeroed and if yes zero it and Mark
//it as done
if (map.containsKey("C" + i) && !map.get("C" + i)) {
for (int j = 0; j < heigth; j++) {
matrix[j][i] = 0;
}
map.put("C" + i, true);
}
}
return matrix;
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 0, 7, 6 }, { 1, 0, 8, 7, 5 }, { 1, 2, 1,
7,-1 }, { 1, 2, 3, 4, 0 } };
print(matrix);
System.out.println("#####################################");
matrix=myFunction(matrix);
print(matrix);
}
public static void print(int[][] matrix) {
int h = matrix.length;
int l = matrix[0].length;
for (int i = 0; i < h; i++) {
for (int j = 0; j < l; j++) {
System.out.print(" " + matrix[i][j] + " ");
}
System.out.println();
}
}
}