修改矩阵并将列和行设置为零的算法

时间:2013-12-13 22:28:23

标签: java arrays algorithm matrix time-complexity

这在技术上是一个代码挑战。 我在接受采访时被问到一个有趣的问题,我希望得到一些见解,因为我能想到的最好的答案是O(2n ^ 2) - n平方类别,但仍然是相当暴力的。

假设您有一个M大小为N的矩阵(数组数组(int[][]))

1 2 4 3 1
0 5 3 7 7
5 8 9 2 8
6 7 0 8 9

如果单元格包含零,则将整个行和列设置为零 结果:

0 2 0 3 1
0 0 0 0 0 
0 8 0 2 8
0 0 0 0 0 

最快和/或最好的方法是什么?


我自己的答案是迭代整个数组,跟踪行和列的归零,然后将它们归零。

public void zeroOut(int[][] myArray){
    ArrayList<Integer> rowsToZero = new....
    ArrayList<Integer> columnsToZero = new....

    for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
        for(int j=0; j<myArray[i].length; i++){
            if(myArray[i][j] == 0){
                if(!rowsToZero.contains(i)) rowsToZero.add(i);
                if(!columnsToZero.contains(j)) columnsToZero.add(j);
            }
        }
    }
    for(int row : rows){ // now zero the rows
        myArray[row] = int[myArray.length];
    }

    for(int i=0; i<myArray.length; i++){
        for(int column: columns){ // now zero the columns
            myArray[i][column] = 0;
        }    
    }
}

有更好的算法吗?是否有更好的数据结构来表示这个矩阵?

5 个答案:

答案 0 :(得分:1)

你可以通过取两个int来做到这一点,但唯一的条件是行和列的数量应小于或等于32.您可以使用大于32但是你必须采取的数组整数。

所以逻辑是:

  • 采取两个整数,即rowcol
  • 遍历矩阵matrix[i][j] = 0,而不是设置rowcol
  • 中的相应位
  • 再次遍历遍历后,如果设置了matrix[i][j] = 0row的相应位,则设置column

时间复杂度相同 O(N^2)但内存效率。请在下面找到我的代码。


检查array[row][col] == 0是否为0而不是设置rc中的相应位。

        int r = 0, c = 0;
        for (int row = 0; row < 5; row++) {
            for (int col = 0; col < 7; col++) {
                if (array[row][col] == 0) {
                    r = r | (1<<row);
                    c = c | (1<<col);
                }
            }
        }

现在,如果设置了任何一个位,则将单元格设置为0。

  for (int row = 0; row < 5; row++) {
        for (int col = 0; col <7; col++) {
            if (((c&(1<<col))!=0) || ((r&(1<<row))!=0)) {
                array[row][col] = 0;  
            }
        }
    }

答案 1 :(得分:0)

如何将矩阵分割成相等的较小矩阵部分并计算阻尼剂,以便您可以预测该矩阵部分中存在零。 然后只使用强力机制对这个预先选定的矩阵进行确定 在零行或列中,零是。

决定因素只是一个建议,也许你可以使用其他类型的线性代数 用于预测零值的算法和规则

更新:

如果您使用Quicksort概念来组织每一行的临时性。然后你只需要循环,直到第一个零零元素出现。 您需要在排序过程中记住哪个列索引与0

相关联

意味着

 1 2 6 0 3

Quciksort(

 0 1 2 4 6

当您记住列索引时,您现在可以直接知道要用0填充哪一行以及哪一列

Quicksort的平均值是O(n log n)Worstcase n * n

也许这已经改善了整体的复杂性。

答案 2 :(得分:0)

似乎到目前为止没有人真正想出一个明显更快/更好的算法,所以这个似乎就是这样。感谢大家的投入。

public void zeroOut(int[][] myArray){
    ArrayList<Integer> rowsToZero = new....
    ArrayList<Integer> columnsToZero = new....

    for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
        for(int j=0; j<myArray[i].length; i++){
            if(myArray[i][j] == 0){
                if(!rowsToZero.contains(i)) rowsToZero.add(i);
                if(!columnsToZero.contains(j)) columnsToZero.add(j);
            }
        }
    }
    for(int row : rows){ // now zero the rows
        myArray[row] = int[myArray.length];
    }

    for(int i=0; i<myArray.length; i++){
        for(int column: columns){ // now zero the columns
            myArray[i][column] = 0;
        }    
    }
}

答案 3 :(得分:0)

我刚刚遇到了这个问题,并为此开发了一个解决方案。 我希望我可以获得一些关于它是如何更好/更差的代码的反馈,以及它的运行时间。 这一切都很新鲜:)

public static void zeroMatrix(int[][] arr1)
{

    ArrayList<Integer> coord = new ArrayList<>();

    int row = arr1.length; 
    int column = arr1[0].length;
    for(int i=0; i < row; i++)
    {
        for(int j=0; j < column; j++)
        {
            if(arr1[i][j]==0)
            { 
                coord.add((10*i) + j);
            }       
        }
    }

    for(int n : coord)
    {
         int j=n%10;
         int i=n/10; int k=0;
        int l=0;
        while(k<row)
        {
            arr1[k][j]=0;
            k++;
        }
        while(l<column)
        {
            arr1[i][l]=0;
            l++;
        }
    }
}

答案 4 :(得分:0)

我使用过HashMap。如果这可以以任何方式提供帮助

import java.util.*;
class ZeroMatrix
{
public static void main(String args[])
{
int mat[][]=new int[][]{{0,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,0}};
HashMap<Integer,Integer> ht=new HashMap<Integer,Integer>();
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
if(mat[i][j]==0)
ht.put(i,j);
}
}

//Set the Respected Rows and colums to Zeros 
Set set=ht.entrySet();
Iterator itr=set.iterator();
while(itr.hasNext())
{
Map.Entry m=(Map.Entry)itr.next();
int i=(Integer)m.getKey();
int k=(Integer)m.getValue();
for(int j=0;j<4;j++)
{
mat[i][j]=0;
}
for(int j=0;j<5;j++)
{
mat[j][k]=0;
}
}

//Printing the Resultant Zero Matrix 

for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
 System.out.print(mat[i][j]);
}
System.out.println();
}
}
}