在Java

时间:2016-04-30 11:02:51

标签: java algorithm matrix

我开始阅读着名的“破解编码面试”一书,我想做以下练习。

  

编写一个算法,使得如果MxN矩阵中的元素为0,则整个行和列都设置为0.

以下是作者的解决方案:

public static void setZeros(int[][] matrix) {
int[] row = new int[matrix.length];
int[] column = new int[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[0].length;j++) {
        if (matrix[i][j] == 0) {
            row[i] = 1;
            column[j] = 1;
        }
    }
}

// Set arr[i][j] to 0 if either row i or column j has a 0
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[0].length; j++) {
        if ((row[i] == 1 || column[j] == 1)) {
             matrix[i][j] = 0;
        }
    }
 }
}

我同意作者的主要观点。我们不必在矩阵中存储'0'的位置,而只需要存储有关的行和列的位置。但是我在她的解决方案中发现有点“奇怪”的是,最后,她在矩阵的所有单元格上做了一个循环,这在我看来是不必要的。

这是我的解决方案:

static int[][] replaceMatrix(int[][] matrix){
  int M = matrix.length;
  int N = matrix[0].length;

  boolean[] row = new boolean[M] ;
  boolean[] column = new boolean[N];

  for (int i =0; i< M; i++) {
    for (int j = 0; j<N; j++ ){
         if (matrix[i][j] == 0) {
            row[i] = true;
            column[j] = true;
         }
    }
  }

  for (int i =0; i<M; i++){
    if (row[i]){
        for (int k =0; k<N; k++){
            matrix[i][k]=0;
        }
    }
  }

  for (int j =0; j<N; j++){
    if (column[j]){
        for (int k =0; k<M; k++){
            matrix[k][j]=0;
        }
    }
  }  

我是编程新手,所以我不能完全确定这一点。但是在我的解决方案中,如果我们除了存储0位置的第一步之外,我的程序的第二部分的时间复杂度为O(M + N),而她的解决方案具有复杂性O(M * N)。

问题是一般复杂性是否相同O(M * N +(M + N))与复杂度O(2 * M * N)相同,不是吗? (我不完全确定)。 例如,如果它是M = N的矩阵,那么两个程序的两个复杂度将是O(M ^ 2)。

我真的想知道在这种情况下复杂性是否存在差异?

ps:我读过用位向量可以改善空间复杂度。但我真的不明白。你能给我一个关于它的一般概念(用Java)吗?

2 个答案:

答案 0 :(得分:2)

最后两个for循环的时间复杂度仍为O(M * N),因为在最坏的情况下,for for循环将运行k次的最大值。

答案 1 :(得分:0)

你和作者的解决方案在技术上没有区别,因为你们两个都遍历了整个矩阵。如果我们必须考虑大O符号**两个代码都是相同的**

实际上作者的代码有点(一点点我不是指不同的时间复杂度更好。原因如下:

假设在您的布尔行数组中,所有行都设置为true。然后在你的情况下,你将遍历所有行和每行的每个元素,这些元素基本上遍历整个矩阵。

假设在您的布尔列数组中,所有列都设置为true。然后在您的情况下,您将遍历所有列并遍历每列的每个元素,这些元素基本上遍历整个矩阵。

所以你实际上遍历整个矩阵两次。但是代码的时间复杂度是相同的,因为O(M * N)和O(2 * M * N)是相同的。

您已经完成了节省空间,因为您使用了布尔数据类型。