diff --git a/DIRECTORY.md b/DIRECTORY.md index 3da24f6e..94efe42a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -187,6 +187,9 @@ * [Diff Elements In List](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/array_diff/diff_elements_in_list.py) * Distinct * [Distinct Values](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/distinct/distinct_values.py) + * Matrix + * Settozero + * [Test Set Matrix Zero](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/matrix/settozero/test_set_matrix_zero.py) * Max Subarray * [Sub Array Maxsum](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/max_subarray/sub_array_maxsum.py) * Minincrementsforunique diff --git a/datastructures/arrays/matrix/settozero/README.md b/datastructures/arrays/matrix/settozero/README.md new file mode 100644 index 00000000..55acffe5 --- /dev/null +++ b/datastructures/arrays/matrix/settozero/README.md @@ -0,0 +1,17 @@ +# Set Matrix Zero + +Given a matrix, mat, if any element within the matrix is zero, set that row and column to zero. The performed operations +should be in place, i.e., the given matrix is modified directly without allocating another matrix. + +Constraints: + +Let `mat` be the matrix given as input for the zeroing operation. + +- 1 <= `mat.row`, `mat.col` <= 20 +- -2^31 <= `mat[i][j]` <= 2^31-1 + +## Examples + +![Example one](images/set_matrix_zero_example_one.png) +![Example two](images/set_matrix_zero_example_two.png) +![Example three](images/set_matrix_zero_example_three.png) diff --git a/datastructures/arrays/matrix/settozero/__init__.py b/datastructures/arrays/matrix/settozero/__init__.py new file mode 100644 index 00000000..9a108808 --- /dev/null +++ b/datastructures/arrays/matrix/settozero/__init__.py @@ -0,0 +1,55 @@ +from typing import List + + +def set_matrix_zeros(mat: List[List[int]]) -> List[List[int]]: + """ + Sets all elements in a matrix to zero if any row or column has at least one zero element. + + ## Complexity Analysis + + This solution is efficient in both time and space. The time complexity is O(rows × cols) because we scan through + the matrix a constant number of times. The space complexity is O(1) because we only use a couple of boolean + variables regardless of the matrix size, and we use the matrix itself for tracking. + + Args: + mat (List): input matrix + Returns: + List[List[int]]: modified matrix with all elements in any row or column containing a zero element set to zero + """ + if not mat or not mat[0]: + return mat + + row_length, col_length = len(mat), len(mat[0]) + + # Step 1: Check if the first row and first column originally contain zeros + # We need this info because we'll use them as markers + first_row_has_zero = any(mat[0][j] == 0 for j in range(col_length)) + first_col_has_zero = any(mat[i][0] == 0 for i in range(row_length)) + + # Step 2: Use first row and column as markers for other rows/columns + # Scan the interior of the matrix (excluding first row and column) + for r in range(1, row_length): + for c in range(1, col_length): + if mat[r][c] == 0: + # Mark this row and column by setting the corresponding + # positions in the first row and column to zero + mat[r][0] = 0 # mark row as 0 + mat[0][c] = 0 # mark column as 0 + + # Step 3: Use the markers to set zeros in the interior of the matrix + # We process from [1][1] onwards to avoid corrupting our markers + for r in range(1, row_length): + for c in range(1, col_length): + # If this row or column was marked, set this cell to zero + if mat[r][0] == 0 or mat[0][c] == 0: + mat[r][c] = 0 + + # Step 4: Finally, handle the first row and column based on our original checks + if first_row_has_zero: + for c in range(col_length): + mat[0][c] = 0 + if first_col_has_zero: + for r in range(row_length): + mat[r][0] = 0 + + return mat diff --git a/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_one.png b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_one.png new file mode 100644 index 00000000..a2d259ba Binary files /dev/null and b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_one.png differ diff --git a/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_three.png b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_three.png new file mode 100644 index 00000000..4ba8d9ba Binary files /dev/null and b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_three.png differ diff --git a/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_two.png b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_two.png new file mode 100644 index 00000000..23f31a96 Binary files /dev/null and b/datastructures/arrays/matrix/settozero/images/set_matrix_zero_example_two.png differ diff --git a/datastructures/arrays/matrix/settozero/test_set_matrix_zero.py b/datastructures/arrays/matrix/settozero/test_set_matrix_zero.py new file mode 100644 index 00000000..cfe6ea80 --- /dev/null +++ b/datastructures/arrays/matrix/settozero/test_set_matrix_zero.py @@ -0,0 +1,38 @@ +import unittest +from . import set_matrix_zeros + + +class SetMatrixZeroTestCase(unittest.TestCase): + def test_1(self): + matrix = [[1,2,3],[4,5,6],[7,0,9]] + expected = [[1,0,3],[4,0,6],[0,0,0]] + actual = set_matrix_zeros(matrix) + self.assertEqual(expected, actual) + + def test_2(self): + matrix = [[1,2,3,4],[4,5,6,7],[8,9,4,6]] + expected = [[1,2,3,4],[4,5,6,7],[8,9,4,6]] + actual = set_matrix_zeros(matrix) + self.assertEqual(expected, actual) + + def test_3(self): + matrix = [[1,1,0,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,0,1,1,1],[1,1,1,1,1]] + expected = [[0, 0, 0, 0, 0], [1, 0, 0, 1, 1], [1, 0, 0, 1, 1], [0, 0, 0, 0, 0], [1, 0, 0, 1, 1]] + actual = set_matrix_zeros(matrix) + self.assertEqual(expected, actual) + + def test_4(self): + matrix = [[1,1,1],[1,0,1],[1,1,1]] + expected = [[1, 0, 1], [0, 0, 0], [1, 0, 1]] + actual = set_matrix_zeros(matrix) + self.assertEqual(expected, actual) + + def test_5(self): + matrix = [[3,5,2,0],[1,0,4,6],[7,3,2,4]] + expected = [[0, 0, 0, 0], [0, 0, 0, 0], [7, 0, 2, 0]] + actual = set_matrix_zeros(matrix) + self.assertEqual(expected, actual) + + +if __name__ == '__main__': + unittest.main()