Алгоритм изменения матрицы и установки столбцов и строк в ноль

технически это вызов кода. Мне задали интересный вопрос на интервью, и я надеюсь на некоторое понимание, поскольку лучшим ответом, который я мог придумать, была категория O(2n^2) - n-squared, но все еще довольно грубая сила.

предположим, у вас есть матрица размером 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 ответов


вы можете сделать это, взяв две int но единственным условием является отсутствие строк и cols должно быть меньше или равно 32. Вы можете сделать то же самое с более чем 32, но вы должны взять массив ints.

Итак, логика:

  • возьмите два Инта, т. е. row и col
  • пересечь матрицу, если matrix[i][j] = 0 чем установить соответствующие биты в row и col
  • после прохождения траверсой и установить matrix[i][j] = 0 если соответствующий бит или row или column установлен.

сложность времени такая же O(N^2) но это эффективная память. Пожалуйста, найдите мой код ниже .


проверить, является ли array[row][col] == 0 если 0, чем установить соответствующий бит в r и c.

        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;  
            }
        }
    }

Как насчет разделения матриц на равные меньшие части Матрицы и вычисления детерминирующего, чтобы вы могли предсказать, что в этой части матрицы есть ноль. И тогда используйте только механизм грубой силы для этих предварительно выбранных матриц для определения в какой строке или столбце равен нулю.

определитель-это просто предложение, возможно, вы можете использовать какой-то другой вид линейной алгебраической алгоритмы и правила для предсказания нулевого значения

обновление:

Если вы используете концепцию Quicksort для организации temporay каждой строки. Затем вам нужно просто выполнить цикл, пока не появится первый нулевой элемент none. Вы должны помнить во время процесса сортировки, какой индекс столбца был связан с 0

означает

 1 2 6 0 3

Quciksort (

 0 1 2 4 6

когда вы помните индекс столбца, вы теперь непосредственно знаете, какую строку заполнить 0 и какой столбец,

среднее значение Quicksort ist O (N log n) Worstcase n * n

может это уже улучшает общее complexisitiy.


Кажется, до сих пор никто не придумал значительно более быстрый/лучший алгоритм, поэтому, похоже, это он. Спасибо всем за Ваш вклад.

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;
        }    
    }
}

Я только что столкнулся с этим вопросом и разработал для него решение. Я надеюсь, что смогу получить некоторую обратную связь для кода о том, как это лучше/хуже, и это время выполнения. Довольно новый для всего этого:)

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++;
        }
    }
}

я использовал 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();
}
}
}