Introduction
Arrays are fundamental data structures widely used in computer science and programming. One intriguing problem that often surfaces when dealing with arrays is the “Set Matrix Zero” problem. This problem challenges programmers to devise an efficient algorithm to set entire rows and columns to zero based on the presence of a zero in a matrix. In this chapter we will delve deep into the problem, understand and explore an effective algorithm to solve it.
Problem Understanding
Consider a matrix:
1 2 3
4 0 6
7 8 9
In this example, the element at the second row and second column is zero. According to the Set Matrix Zero problem, if any element in the matrix is zero, the entire row and column containing that element should be set to zero. Applying this rule to our example, the modified matrix should look like this:
1 0 3
0 0 0
7 0 9
The challenge lies in achieving this without utilizing additional memory, thereby maintaining the integrity of the original matrix.
Algorithm
To tackle this problem, we can follow a straightforward algorithm. We traverse the matrix, identify the cells containing zeroes, and use the first row and first column to mark the corresponding rows and columns that need to be zeroed out. However, since the first row and first column are used as markers, we need to handle them separately.
- Traverse the matrix and mark the first row and first column based on zero elements.
- Iterate through the matrix again, setting the entire row and column to zero if the corresponding first row or first column is marked.
- Finally, check if the first row and first column need to be zeroed out and update accordingly.
Code Implementation
#include <iostream>
#include <vector>
using namespace std;
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
bool firstRowZero = false;
bool firstColZero = false;
// Check if the first row needs to be zeroed out
for (int j = 0; j < n; ++j) {
if (matrix[0][j] == 0) {
firstRowZero = true;
break;
}
}
// Check if the first column needs to be zeroed out
for (int i = 0; i < m; ++i) {
if (matrix[i][0] == 0) {
firstColZero = true;
break;
}
}
// Mark the first row and first column based on zero elements
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;
}
}
}
// Set entire rows and columns to zero based on first row and first column markers
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
// Update the first row if needed
if (firstRowZero) {
for (int j = 0; j < n; ++j) {
matrix[0][j] = 0;
}
}
// Update the first column if needed
if (firstColZero) {
for (int i = 0; i < m; ++i) {
matrix[i][0] = 0;
}
}
}
int main() {
// Example usage
vector<vector<int>> matrix = {
{1, 2, 3},
{4, 0, 6},
{7, 8, 9}
};
setZeroes(matrix);
// Display the modified matrix
for (const auto& row : matrix) {
for (int val : row) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
Complexity Analysis
- Time Complexity:
O(m * n)
- We traverse the entire matrix twice. - Space Complexity:
O(1)
- No additional space is used, meeting the requirement of the problem.