Set Matrix Zeros

Hero Image

DT

Dhaval Trivedi

Co-founder, Airtribe

Problem Overview

The "Set Matrix Zeroes" problem is a classic problem in the array category on LeetCode (Problem No. 73). The objective is to modify a given matrix such that if an element is zero, its entire row and column are set to zero. This must be done in-place, without using additional storage for another matrix.

In essence, the challenge is to efficiently manage how zeros are propagated throughout the matrix without utilizing extra space proportionate to the matrix’s size.

Understanding the Problem

Given a matrix comprised of integers, you are tasked with setting the entire row and column of any element that is zero to zeroes. The trick is to achieve this transformation in-place, maintaining the space complexity to a minimum.

For example:

Input: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]

Output: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

When you encounter a zero at position (i, j) in the matrix, you need to set all elements in the i-th row and j-th column to zero.

Key DSA Concepts and Theory

Arrays

This problem revolves around two-dimensional arrays. Arrays are a data structure that store elements in contiguous memory locations. A 2D array can be imagined as a matrix, where each element is identified by two indices.

In-place Algorithm

An in-place algorithm transforms the input using a small, constant amount of space. It is crucial in optimizing space complexity, which is one of the main constraints in this problem.

Marking Technique

One common method for solving in-place problems is marking the elements that need to be changed without requiring additional memory. In this problem, we can utilize markers on certain columns or rows to keep track of which rows/columns need to be zeroed.

Solution Approach

Step-by-Step Solution

  1. First Pass (Marking): Traverse the matrix and use the first row and first column to mark whether a particular row or column should be set to zero.

    • Use two flags, isFirstRowZero and isFirstColZero, to check if the first row or column itself should be entirely zero.
  2. Second Pass (Zeroing from Markers): Iterate through the matrix and use the marks set in the first step to zero out rows and columns.

  3. Final Adjustment: Finally, if the first row or column needed to be zeroed, apply the changes based on the initial flag setup.

Here's the implementation in both C++ and Java:

C++ Implementation

#include <vector>
using namespace std;

void setZeroes(vector<vector<int>>& matrix) {
    bool isFirstRowZero = false;
    bool isFirstColZero = false;
    int rows = matrix.size();
    int cols = matrix[0].size();

    // Determine if the first row or first column has any zeros
    for (int j = 0; j < cols; j++) {
        if (matrix[0][j] == 0) {
            isFirstRowZero = true;
            break;
        }
    }
    for (int i = 0; i < rows; i++) {
        if (matrix[i][0] == 0) {
            isFirstColZero = true;
            break;
        }
    }

    // Use first row and column to mark zeros
    for (int i = 1; i < rows; i++) {
        for (int j = 1; j < cols; j++) {
            if (matrix[i][j] == 0) {
                matrix[i][0] = 0;
                matrix[0][j] = 0;
            }
        }
    }

    // Zero out cells based on marks
    for (int i = 1; i < rows; i++) {
        for (int j = 1; j < cols; j++) {
            if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                matrix[i][j] = 0;
            }
        }
    }

    // Zero out the first row and column if needed
    if (isFirstRowZero) {
        for (int j = 0; j < cols; j++) {
            matrix[0][j] = 0;
        }
    }
    if (isFirstColZero) {
        for (int i = 0; i < rows; i++) {
            matrix[i][0] = 0;
        }
    }
}

Java Implementation

public class Solution {
    public void setZeroes(int[][] matrix) {
        boolean isFirstRowZero = false;
        boolean isFirstColZero = false;
        int rows = matrix.length;
        int cols = matrix[0].length;

        // Determine if the first row or first column has any zeros
        for (int j = 0; j < cols; j++) {
            if (matrix[0][j] == 0) {
                isFirstRowZero = true;
                break;
            }
        }
        for (int i = 0; i < rows; i++) {
            if (matrix[i][0] == 0) {
                isFirstColZero = true;
                break;
            }
        }

        // Use first row and column to mark zeros
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < cols; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }

        // Zero out cells based on marks
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < cols; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }

        // Zero out the first row and column if needed
        if (isFirstRowZero) {
            for (int j = 0; j < cols; j++) {
                matrix[0][j] = 0;
            }
        }
        if (isFirstColZero) {
            for (int i = 0; i < rows; i++) {
                matrix[i][0] = 0;
            }
        }
    }
}

Time and Space Complexity Analysis

Time Complexity

The time complexity of this algorithm is O(n * m) where n is the number of rows and m is the number of columns. This is because the matrix is traversed a constant number of times, each involving iterating through all elements.

Space Complexity

The space complexity is O(1), beyond the input matrix itself. This is due to the use of existing rows and columns to store markers, avoiding any significant extra memory allocation.

Common Mistakes to Avoid

  1. Additional Space Usage: A common misconception is that a secondary data structure is necessary to keep track of zero positions. However, this approach can be avoided or optimized.

  2. Ignoring Edge Cases: Make sure to handle edge cases where matrices have dimensions of size 1 or when the entire row or column is zero.

Similar Problems on LeetCode

Additional Resources and References

This article outlines the challenge of effectively transforming a matrix based on specific conditions using strategic in-place operations. By adeptly marking necessary changes, we optimized our space usage while maintaining a manageable time complexity—ensuring that solutions are both elegant and efficient.