Skip to content

Create largest_square_area_in_matrix.py #7673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions matrix/largest_square_area_in_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
"""
Question:
Given a binary matrix mat of size n * m, find out the maximum size square
sub-matrix with all 1s.

---
Example 1:

Input:
n = 2, m = 2
mat = [[1, 1],
[1, 1]]

Output:
2

Explaination: The maximum size of the square
sub-matrix is 2. The matrix itself is the
maximum sized sub-matrix in this case.
---
Example 2

Input:
n = 2, m = 2
mat = [[0, 0],
[0, 0]]
Output: 0

Explaination: There is no 1 in the matrix.


Approch:
We initialize another matrix (dp) with the same dimensions
as the original one initialized with all 0’s.

dp_array(i,j) represents the side length of the maximum square whose
bottom right corner is the cell with index (i,j) in the original matrix.

Starting from index (0,0), for every 1 found in the original matrix,
we update the value of the current element as

dp_array(i,j)=dp_array(dp(i−1,j),dp_array(i−1,j−1),dp_array(i,j−1)) + 1.
"""


from typing import List


def largest_square_area_in_matrix_top_down_approch(
rows: int, cols: int, mat: list[list[int]]
) -> int:
"""
Function updates the largest_square_area[0], if recursive call found
square with maximum area.

We arent using dp_array here, so the time complexity would be exponential.

>>> largest_square_area_in_matrix_top_down_approch(2, 2, [[1,1], [1,1]])
2
>>> largest_square_area_in_matrix_top_down_approch(2, 2, [[0,0], [0,0]])
0
"""

def update_area_of_max_square(row: int, col: int) -> int:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square


# BASE CASE
if row >= rows or col >= cols:
return 0

right = update_area_of_max_square(row, col + 1)
diagonal = update_area_of_max_square(row + 1, col + 1)
down = update_area_of_max_square(row + 1, col)

if mat[row][col]:
sub_problem_sol = 1 + min([right, diagonal, down])
largest_square_area[0] = max(largest_square_area[0], sub_problem_sol)
return sub_problem_sol
else:
return 0

largest_square_area = [0]
update_area_of_max_square(0, 0)
return largest_square_area[0]


def largest_square_area_in_matrix_top_down_approch_with_dp(
rows: int, cols: int, mat: list[list[int]]
) -> int:
"""
Function updates the largest_square_area[0], if recursive call found
square with maximum area.

We are using dp_array here, so the time complexity would be O(N^2).

>>> largest_square_area_in_matrix_top_down_approch_with_dp(2, 2, [[1,1], [1,1]])
2
>>> largest_square_area_in_matrix_top_down_approch_with_dp(2, 2, [[0,0], [0,0]])
0
"""

def update_area_of_max_square_using_dp_array(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square_using_dp_array

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square_using_dp_array

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square_using_dp_array

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square_using_dp_array

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file matrix/largest_square_area_in_matrix.py, please provide doctest for the function update_area_of_max_square_using_dp_array

row: int, col: int, dp_array: list[list[int]]
) -> int:
if row >= rows or col >= cols:
return 0
if dp_array[row][col] != -1:
return dp_array[row][col]

right = update_area_of_max_square_using_dp_array(row, col + 1, dp_array)
diagonal = update_area_of_max_square_using_dp_array(row + 1, col + 1, dp_array)
down = update_area_of_max_square_using_dp_array(row + 1, col, dp_array)

if mat[row][col]:
sub_problem_sol = 1 + min([right, diagonal, down])
largest_square_area[0] = max(largest_square_area[0], sub_problem_sol)
dp_array[row][col] = sub_problem_sol
return sub_problem_sol
else:
return 0

largest_square_area = [0]
dp_array = [[-1] * cols for _ in range(rows)]
update_area_of_max_square_using_dp_array(0, 0, dp_array)

return largest_square_area[0]


def largest_square_area_in_matrix_bottom_up(
rows: int, cols: int, mat: list[list[int]]
) -> int:
"""
Function updates the largest_square_area, using bottom up approch.

>>> largest_square_area_in_matrix_bottom_up(2, 2, [[1,1], [1,1]])
2
>>> largest_square_area_in_matrix_bottom_up(2, 2, [[0,0], [0,0]])
0

"""
dp_array = [[0] * (cols + 1) for _ in range(rows + 1)]
largest_square_area = 0
for row in range(rows - 1, -1, -1):
for col in range(cols - 1, -1, -1):

right = dp_array[row][col + 1]
diagonal = dp_array[row + 1][col + 1]
bottom = dp_array[row + 1][col]

if mat[row][col] == 1:
dp_array[row][col] = 1 + min(right, diagonal, bottom)
largest_square_area = max(dp_array[row][col], largest_square_area)
else:
dp_array[row][col] = 0

return largest_square_area


def largest_square_area_in_matrix_bottom_up_space_optimization(
rows: int, cols: int, mat: list[list[int]]
) -> int:
"""
Function updates the largest_square_area, using bottom up approch. with space optimization.

>>> largest_square_area_in_matrix_bottom_up_space_optimization(2, 2, [[1,1], [1,1]])
2
>>> largest_square_area_in_matrix_bottom_up_space_optimization(2, 2, [[0,0], [0,0]])
0
"""
current_row = [0] * (cols + 1)
next_row = [0] * (cols + 1)
largest_square_area = 0
for row in range(rows - 1, -1, -1):
for col in range(cols - 1, -1, -1):

right = current_row[col + 1]
diagonal = next_row[col + 1]
bottom = next_row[col]

if mat[row][col] == 1:
current_row[col] = 1 + min(right, diagonal, bottom)
largest_square_area = max(current_row[col], largest_square_area)
else:
current_row[col] = 0
next_row = current_row

return largest_square_area


if __name__ == "__main__":
import doctest

doctest.testmod()
# print(largest_square_area_in_matrix_bottom_up(2, 2, [[1,1], [1,1]]))