Home > OS >  Set matrix zeroes
Set matrix zeroes

Time:07-12

Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0's. I have tried taking the approach where we set row 1 and column 1 as reference rows and columns. I am getting following run-time error on running the code: "ERROR: AddressSanitizer: heap-buffer-overflow on address...."

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int x=1, y=1, col=1,row=1;
    int m=matrix.size();
    int n=matrix[0].size();
    //for 1st row i.e considered as reference row for inner matrix
    for(int i=0;i<m;i  ){
        if(matrix[i][0]==0)
            x=0;
    }
    // for 1st column i.e considered as reference column for inner matrix;
    for(int a=0;a<n;a  ){
        if(matrix[0][a]==0)
            y=0;
    }
    //loop for the inner matrix
    for(int i=1;i<m;i  ){
        for(int j=1;j<n;j  ){
            if(matrix[i][j]==0){
                matrix[0][j]=0;
                matrix[i][0]=0;
            }
        }
    }
    //for iterating over 1st row of the matrix to check for zeroes.
    for(int i=1;i<m;i  ){
        if(matrix[0][i]==0){
            while(i<n){
                matrix[i][col]=0;
                col  ;
            };
            break;
        }
    }
    //for iterating over 1 column of the matrix to check for zeroes
    for(int j=1;j<n;j  ){
        if(matrix[j][0]==0){
            while(j<m){
                matrix[row][j]=0;
                row  ;
            };
            break;
        }
    }
    if(x==0){
        for(int i=0;i<m;i  )
            matrix[0][i]=0;
    }
    if(y==0){
        for(int j=0;j<n;j  )
        matrix[j][0]=0;
    }
}
};

CodePudding user response:

instead of declaring col and row, use a nested loop in order to iterate over 1st row and 1st column. other than this, there are certain errors in the code. The final code is given below:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int x=1, y=1;
    int m=matrix.size();
    int n=matrix[0].size();
    //for 1st row i.e considered as pointer row for inner matrix
    for(int j=0;j<n;j  ){
        if(matrix[0][j]==0)
            x=0;
    }
    // for 1st column i.e considered as pointer column for inner matrix;
    for(int i=0;i<m;i  ){
        if(matrix[i][0]==0)
            y=0;
    }
    //loop for the inner matrix
    for(int i=1;i<m;i  ){
        for(int j=1;j<n;j  ){
            if(matrix[i][j]==0){
                matrix[i][0]=0;
                matrix[0][j]=0;
            }
        }
    }
    //for iterating over 1st row of the matrix to check for zeroes.
    for(int i=1;i<m;i  ){
        if(matrix[i][0]==0){
            for(int j=1;j<n;j  )
            matrix[i][j]=0;
        }
    }
    //for iterating over 1 column of the matrix to check for zeroes
    for(int j=1;j<n;j  ){
        if(matrix[0][j]==0){
            for(int i=1;i<m;i  )
                matrix[i][j]=0;
        }
    }
    if(x==0){
        for(int j=0;j<n;j  )
            matrix[0][j]=0;
    }
    if(y==0){
        for(int i=0;i<m;i  )
        matrix[i][0]=0;
    }
    }
};

CodePudding user response:

Let's check one the last loops in the posted code

void setZeroes(vector<vector<int>>& matrix) {
    // ...     ^^^^^^^^^^^^^^^^^^^            I assume a row-major representation 
    int col=1,row=1;
    
    int m = matrix.size();
    //  ^^^^^^^^^^^^^^^^^        Let's call it the number of rows.
    int n = matrix[0].size();
    //  ^^^^^^^^^^^^^^^^^^^^     That's the number of columns. Let's "hope" that
    //                           the vector isn't empty and that all the rows
    //                           have the same number of columns.
    
    // ...

    for(int i=1;i<m;i  ){
    //          ^^^              Note the limit: 'm', which is the number of rows.
        if(matrix[0][i]==0){
        //          ^^^          We are traversing the first row, but if 'n' < 'm'
        //                       that access has undefined behavior.
            
        //  Now, I guess you'd want to zero an entire column, but it should
        //  be the one where the zero in the first row is.
            while( i < n ){
                // ^^^^^         So, what does 'i' represents now?
                matrix[i][col]=0;
                //     ^^^^^^    are you trying to access a row or a column?
                col  ;
                //               'i' isn't modified, so this loop is either
                //               infinite or never executed.
            };
            break; //            Why? Why is it here?          
        }
    }
    // ...
}

A possible implementation of this algorithm (the one that solves the problem using O(1) additional space) is the following:

#include <algorithm>
#include <vector>

void setZeroes(std::vector<std::vector<int>>& matrix)
{
  if ( matrix.empty() ) return;

  // Use the first row and column to memorize which column or row to set to zero.
  // matrix[0][0] is used for the first row, so we need an extra variable for
  // the first column.
  bool first_column_has_zero{};
  for ( size_t i{}; i < matrix.size();   i )
  {
    if ( matrix[i][0] == 0 )
      first_column_has_zero = true;
    for ( size_t j{1}; j < matrix[i].size();   j )
    {
      if ( matrix[i][j] == 0 )
      {
        matrix[0][j] = 0;
        matrix[i][0] = 0;
      }
    }
  }

  // Now modify all the rows and columns other than the first ones.
  for ( size_t i{1}; i < matrix.size();   i )
  {
    if ( matrix[i][0] == 0 )
    {
      std::fill(matrix[i].begin()   1, matrix[i].end(), 0);
    }
    else
    {
      for ( size_t j{1}; j < matrix[i].size();   j )
      {
        if ( matrix[0][j] == 0 )
          matrix[i][j] = 0;
      }
    }
  }

  // At last, deal with the first row and column.
  if ( matrix[0][0] == 0 )
    std::fill(matrix[0].begin(), matrix[0].end(), 0);

  if ( first_column_has_zero )
    for ( size_t i{}; i < matrix.size();   i )
    {
      matrix[i][0] = 0;
    }
}

I actually prefer the one that is O(n m) in space, because it's more straightforward, but your mileage may vary:

#include <algorithm>
#include <vector>

void setZeroes(std::vector<std::vector<int>>& matrix)
{
  if ( matrix.empty() ) return;

  std::vector<bool> rows(matrix.size());
  std::vector<bool> cols(matrix[0].size());

  for ( size_t i{}; i < matrix.size();   i )
  {
    // assert(matrix[i].size() == cols.size());
    for ( size_t j{}; j < cols.size();   j )
    {
      if ( matrix[i][j] == 0 )
      {
        rows[i] = true;
        cols[j] = true;
      }
    }
  }

  for ( size_t i{}; i < matrix.size();   i )
  {
    if ( rows[i] )
    {
      std::fill(matrix[i].begin(), matrix[i].end(), 0);
    }
    else
    {
      std::transform( matrix[i].begin(), matrix[i].end()
                    , cols.cbegin()
                    , matrix[i].begin()
                    , [](auto a, auto b){ return b ? 0 : a; });
    }
  }
}
  • Related