Given a boolean matrix mat[][] where each cell contains either 0 or 1, modify the matrix such that if a matrix cell mat[i][j] is 1 then all the cells in its ith row and jth column will become 1.
Examples:
Input: mat[][]= [[1, 0],
[0, 0]]
Output: [[1, 1],
[1, 0]]Input: mat[][]= [[1, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0]]
Output: [[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 0, 1, 1]]
Table of Content
[Naive Approach] - Marking the Matrix - O((n × m) × (n+m)) Time and O(1) Space
Assuming all the elements in the matrix are non-negative, traverse through the matrix.
- If you find an element with the value 1, change all the zeros in its row and column to -1.
- The reason for using -1 instead of 1 is to avoid affecting other rows and columns during the traversal.
- Finally traverse through the matrix again and if an element is -1 change it to 1.
#include <iostream>
#include <vector>
using namespace std;
void booleanMatrix(vector<vector<int>>& mat) {
int rows = mat.size(), cols = mat[0].size();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == 1) {
// Replace all the zeros in jth column by -1
for (int idx = 0; idx < rows; idx++) {
if (mat[idx][j] == 0) {
mat[idx][j] = -1;
}
}
// Replace all the zeros in ith row by -1
for (int idx = 0; idx < cols; idx++) {
if (mat[i][idx] == 0) {
mat[i][idx] = -1;
}
}
}
}
}
// Replace all the -1 by 1
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == -1) {
mat[i][j] = 1;
}
}
}
}
int main() {
vector<vector<int>> mat = {{1, 0, 0, 1}, {0, 0, 1, 0}, {0, 0, 0, 0}};
booleanMatrix(mat);
for (const vector<int>& row : mat) {
for (int val : row) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
class GfG {
static void booleanMatrix(int[][] mat) {
int rows = mat.length, cols = mat[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == 1) {
// Replace all the zeros in jth column by -1
for (int idx = 0; idx < rows; idx++) {
if (mat[idx][j] == 0) {
mat[idx][j] = -1;
}
}
// Replace all the zeros in ith row by -1
for (int idx = 0; idx < cols; idx++) {
if (mat[i][idx] == 0) {
mat[i][idx] = -1;
}
}
}
}
}
// Replace all the -1 by 1
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == -1) {
mat[i][j] = 1;
}
}
}
}
public static void main(String[] args) {
int[][] mat = {{1, 0, 0, 1}, {0, 0, 1, 0}, {0, 0, 0, 0}};
booleanMatrix(mat);
for (int[] row : mat) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
}
}
def booleanMatrix(mat):
rows = len(mat)
cols = len(mat[0])
for i in range(rows):
for j in range(cols):
if mat[i][j] == 1:
# Replace all the zeros in jth column by -1
for idx in range(rows):
if mat[idx][j] == 0:
mat[idx][j] = -1
# Replace all the zeros in ith row by -1
for idx in range(cols):
if mat[i][idx] == 0:
mat[i][idx] = -1
# Replace all the -1 by 1
for i in range(rows):
for j in range(cols):
if mat[i][j] == -1:
mat[i][j] = 1
# Driver code
mat = [
[1, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0]
]
booleanMatrix(mat)
for row in mat:
print(*row)
using System;
using System.Collections.Generic;
class GFG
{
static void booleanMatrix(List<List<int>> mat)
{
int rows = mat.Count;
int cols = mat[0].Count;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (mat[i][j] == 1)
{
// Replace all the zeros in jth column by -1
for (int idx = 0; idx < rows; idx++)
{
if (mat[idx][j] == 0)
{
mat[idx][j] = -1;
}
}
// Replace all the zeros in ith row by -1
for (int idx = 0; idx < cols; idx++)
{
if (mat[i][idx] == 0)
{
mat[i][idx] = -1;
}
}
}
}
}
// Replace all the -1 by 1
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (mat[i][j] == -1)
{
mat[i][j] = 1;
}
}
}
}
static void Main()
{
List<List<int>> mat = new List<List<int>>
{
new List<int> { 1, 0, 0, 1 },
new List<int> { 0, 0, 1, 0 },
new List<int> { 0, 0, 0, 0 }
};
booleanMatrix(mat);
for (int i = 0; i < mat.Count; i++)
{
for (int j = 0; j < mat[i].Count; j++)
{
Console.Write(mat[i][j] + " ");
}
Console.WriteLine();
}
}
}
function booleanMatrix(mat) {
let rows = mat.length, cols = mat[0].length;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (mat[i][j] === 1) {
// Replace all the zeros in jth column by -1
for (let idx = 0; idx < rows; idx++) {
if (mat[idx][j] === 0) {
mat[idx][j] = -1;
}
}
// Replace all the zeros in ith row by -1
for (let idx = 0; idx < cols; idx++) {
if (mat[i][idx] === 0) {
mat[i][idx] = -1;
}
}
}
}
}
// Replace all the -1 by 1
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (mat[i][j] === -1) {
mat[i][j] = 1;
}
}
}
}
// Driver Code
let mat = [[1, 0, 0, 1], [0, 0, 1, 0], [0, 0, 0, 0]];
booleanMatrix(mat);
mat.forEach(row => {
console.log(row.join(' '));
});
Output
1 1 1 1 1 1 1 1 1 0 1 1
[Better Approach] - Extra Space - O(n × m) Time and O(n + m) Space
The idea is to use two temporary arrays, rowMarker[] and colMarker[], to keep track of which rows and columns need to be updated.
Following are the steps for this approach
- Create two temporary arrays rowMarker[] and colMarker[]. Initialize all values of rowMarker[] and colMarker[] as 0.
- Traverse the input matrix mat[][]. If you finds mat[i][j] as 1, then mark rowMarker[i] and colMarker[j] as true.
- Traverse the input matrix mat[][] again. For each entry mat[i][j], check the values of rowMarker[i] and colMarker[j]. If any of the two values (rowMarker[i] or colMarker[j]) is true, then mark mat[i][j] as 1.
#include <iostream>
#include <vector>
using namespace std;
void booleanMatrix(vector<vector<int>>& mat) {
int rows = mat.size();
int cols = mat[0].size();
// Arrays to keep track of rows and columns to be updated
vector<bool> rowMarker(rows, false);
vector<bool> colMarker(cols, false);
// Mark the rows and columns that need to be updated
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == 1) {
rowMarker[i] = true;
colMarker[j] = true;
}
}
}
// Update the matrix
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (rowMarker[i] || colMarker[j]) {
mat[i][j] = 1;
}
}
}
}
int main() {
vector<vector<int>> mat = {
{1, 0, 0, 1},
{0, 0, 1, 0},
{0, 0, 0, 0}
};
booleanMatrix(mat);
for (const vector<int>& row : mat) {
for (int val : row) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
class GfG {
static void booleanMatrix(int mat[][]) {
int rows = mat.length;
int cols = mat[0].length;
// Arrays to keep track of rows and columns to be marked
boolean[] rowMarker = new boolean[rows];
boolean[] colMarker = new boolean[cols];
// First pass: Mark the rows and columns to be updated
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == 1) {
rowMarker[i] = true;
colMarker[j] = true;
}
}
}
// Second pass: Update the matrix
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (rowMarker[i] || colMarker[j]) {
mat[i][j] = 1;
}
}
}
}
public static void main(String[] args) {
int[][] arr = {
{ 1, 0, 0, 1 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 }
};
booleanMatrix(arr);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
def booleanMatrix(mat):
rows = len(mat)
cols = len(mat[0])
# Arrays to keep track of rows and columns to be updated
rowMarker = [False] * rows
colMarker = [False] * cols
# First pass: Mark the rows and columns to be updated
for i in range(rows):
for j in range(cols):
if mat[i][j] == 1:
rowMarker[i] = True
colMarker[j] = True
# Second pass: Update the matrix
for i in range(rows):
for j in range(cols):
if rowMarker[i] or colMarker[j]:
mat[i][j] = 1
if __name__ == "__main__":
arr = [[1, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0]]
booleanMatrix(arr)
for row in arr:
print(" ".join(map(str, row)))
using System;
using System.Collections.Generic;
class GfG {
static void booleanMatrix(List<List<int>> mat) {
int rows = mat.Count;
int cols = mat[0].Count;
// Arrays to keep track of rows and columns to be updated
bool[] rowMarker = new bool[rows];
bool[] colMarker = new bool[cols];
// First pass: Mark the rows and columns to be updated
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat[i][j] == 1) {
rowMarker[i] = true;
colMarker[j] = true;
}
}
}
// Second pass: Update the matrix
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (rowMarker[i] || colMarker[j]) {
mat[i][j] = 1;
}
}
}
}
// Test the BooleanMatrix function with a sample input
static void Main(string[] args) {
List<List<int>> arr = new List<List<int>> {
new List<int>{ 1, 0, 0, 1 },
new List<int>{ 0, 0, 1, 0 },
new List<int>{ 0, 0, 0, 0 }
};
booleanMatrix(arr);
foreach (var row in arr) {
Console.WriteLine(string.Join(" ", row));
}
}
}
function booleanMatrix(mat) {
const rows = mat.length;
const cols = mat[0].length;
// Arrays to keep track of rows and columns to be
// updated
const rowMarker = new Array(rows).fill(false);
const colMarker = new Array(cols).fill(false);
// First pass: Mark the rows and columns to be updated
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (mat[i][j] === 1) {
rowMarker[i] = true;
colMarker[j] = true;
}
}
}
// Second pass: Update the matrix
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (rowMarker[i] || colMarker[j]) {
mat[i][j] = 1;
}
}
}
}
// Driver Code
const arr = [ [ 1, 0, 0, 1 ],
[ 0, 0, 1, 0 ],
[ 0, 0, 0, 0 ] ];
booleanMatrix(arr);
arr.forEach(row => console.log(row.join(" ")));
Output
1 1 1 1 1 1 1 1 1 0 1 1
[Expected Approach] - Without Extra Space - O(n × m) Time and O(1) Space
Instead of two auxiliary arrays, we use the first row and first column of the matrix for the same work.
- During the second traversal, updating the first row or first column too early may affect the remaining cells. Therefore, we traverse the matrix in reverse order to avoid incorrect updates.
- Since
mat[0][0]is common to both the first row and first column, we use a separate variablecol0to track whether the first column should be updated. The value ofmat[0][0]is used to determine whether the first row should be updated. - Finally, traverse the matrix from bottom-right to top-left. For each cell, if
mat[i][0] == 1ormat[0][j] == 1, setmat[i][j] = 1; otherwise, leave it unchanged.
#include <iostream>
#include <vector>
using namespace std;
void booleanMatrix(vector<vector<int>>& mat) {
int col0 = 0, rows = mat.size(),
cols = mat[0].size();
// Step 1: Mark the first row and
// column if there is a 1 in the matrix
for (int i = 0; i < rows; i++) {
// Check if 0th column contains 1
if (mat[i][0] == 1) col0 = 1;
for (int j = 1; j < cols; j++) {
if (mat[i][j] == 1) {
mat[i][0] = 1;
mat[0][j] = 1;
}
}
}
// Step 2: Traverse the matrix in
// reverse direction and update values
for (int i = rows - 1; i >= 0; i--) {
for (int j = cols - 1; j >= 1; j--) {
if (mat[i][0] == 1 || mat[0][j] == 1) {
mat[i][j] = 1;
}
}
if (col0 == 1) {
mat[i][0] = 1;
}
}
}
int main() {
vector<vector<int>> arr = {{1, 0, 0, 1},
{0, 0, 1, 0},
{0, 0, 0, 0}};
booleanMatrix(arr);
for (int i = 0; i < arr.size(); i++) {
for (int j = 0; j < arr[0].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
class GfG {
static void booleanMatrix(int mat[][]) {
int col0 = 0;
int rows = mat.length, cols = mat[0].length;
// Step 1: Mark the first row and
// column if there is a 1 in the matrix
for (int i = 0; i < rows; i++) {
// Check if 0th column contains 1
if (mat[i][0] == 1) col0 = 1;
for (int j = 1; j < cols; j++) {
if (mat[i][j] == 1) {
mat[i][0] = 1;
mat[0][j] = 1;
}
}
}
// Step 2: Traverse the matrix in reverse
// direction and update values
for (int i = rows - 1; i >= 0; i--) {
for (int j = cols - 1; j >= 1; j--) {
if (mat[i][0] == 1 || mat[0][j] == 1) {
mat[i][j] = 1;
}
}
if (col0 == 1) {
mat[i][0] = 1;
}
}
}
public static void main(String[] args) {
int[][] arr = {
{1, 0, 0, 1},
{0, 0, 1, 0},
{0, 0, 0, 0}
};
booleanMatrix(arr);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
def booleanMatrix(mat):
col0 = 0
rows = len(mat)
cols = len(mat[0])
# Step 1: Mark the first row and column
# if there is a 1 in the matrix
for i in range(rows):
# Check if 0th column contains 1
if mat[i][0] == 1:
col0 = 1
for j in range(1, cols):
if mat[i][j] == 1:
mat[i][0] = 1
mat[0][j] = 1
# Step 2: Traverse the matrix in reverse
# direction and update values
for i in range(rows - 1, -1, -1):
for j in range(cols - 1, 0, -1):
if mat[i][0] == 1 or mat[0][j] == 1:
mat[i][j] = 1
if col0 == 1:
mat[i][0] = 1
if __name__ == "__main__":
arr = [
[1, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0]
]
booleanMatrix(arr)
for row in arr:
print(" ".join(map(str, row)))
using System;
using System.Collections.Generic;
class GfG
{
static void booleanMatrix(List<List<int>> mat)
{
int col0 = 0;
int rows = mat.Count;
int cols = mat[0].Count;
// Step 1: Mark the first row and column
for (int i = 0; i < rows; i++)
{
if (mat[i][0] == 1)
col0 = 1;
for (int j = 1; j < cols; j++)
{
if (mat[i][j] == 1)
{
mat[i][0] = 1;
mat[0][j] = 1;
}
}
}
// Step 2: Traverse in reverse direction
for (int i = rows - 1; i >= 0; i--)
{
for (int j = cols - 1; j >= 1; j--)
{
if (mat[i][0] == 1 || mat[0][j] == 1)
mat[i][j] = 1;
}
if (col0 == 1)
mat[i][0] = 1;
}
}
static void Main()
{
List<List<int>> mat = new List<List<int>>
{
new List<int> { 1, 0, 0, 1 },
new List<int> { 0, 0, 1, 0 },
new List<int> { 0, 0, 0, 0 }
};
booleanMatrix(mat);
foreach (List<int> row in mat)
{
foreach (int val in row)
{
Console.Write(val + " ");
}
Console.WriteLine();
}
}
}
function booleanMatrix(mat) {
let col0 = 0;
const rows = mat.length;
const cols = mat[0].length;
// Step 1: Mark the first row and column
// if there is a 1 in the matrix
for (let i = 0; i < rows; i++) {
// Check if 0th column contains 1
if (mat[i][0] === 1) col0 = 1;
for (let j = 1; j < cols; j++) {
if (mat[i][j] === 1) {
mat[i][0] = 1;
mat[0][j] = 1;
}
}
}
// Step 2: Traverse the matrix in reverse direction and update values
for (let i = rows - 1; i >= 0; i--) {
for (let j = cols - 1; j >= 1; j--) {
if (mat[i][0] === 1 || mat[0][j] === 1) {
mat[i][j] = 1;
}
}
if (col0 === 1) {
mat[i][0] = 1;
}
}
}
// Driver Code
const arr = [
[1, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0]
];
booleanMatrix(arr);
for (let i = 0; i < arr.length; i++) {
console.log(arr[i].join(" "));
}
Output
1 1 1 1 1 1 1 1 1 0 1 1