Skip to content

Commit 4925964

Browse files
authored
Merge pull request #157 from BrianLusina/feat/algorithms-dynamic-programming-maximal-square
feat(algorithms, dynamic programming): maximal square
2 parents 0b0c41e + ffd6619 commit 4925964

File tree

12 files changed

+146
-2
lines changed

12 files changed

+146
-2
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
* [Test Knapsack 01](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/dynamic_programming/knapsack_01/test_knapsack_01.py)
7272
* Longest Common Subsequence
7373
* [Test Longest Common Subsequence](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/dynamic_programming/longest_common_subsequence/test_longest_common_subsequence.py)
74+
* Maximal Square
75+
* [Test Maximal Square](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/dynamic_programming/maximal_square/test_maximal_square.py)
7476
* Min Distance
7577
* [Test Min Distance](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/dynamic_programming/min_distance/test_min_distance.py)
7678
* Min Path Sum
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Maximal Square
2+
3+
Given an m x n binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.
4+
5+
## Examples
6+
7+
```text
8+
matrix = [
9+
[0, 0, 1, 0, 0],
10+
[1, 1, 1, 0, 1],
11+
[0, 1, 1, 0, 0]
12+
]
13+
14+
Output: 4
15+
```
16+
17+
## Solution
18+
19+
The solution uses bottom-up dynamic programming to solve the problem. The solution is based on the observation that the
20+
size of the largest square ending (bottom-right corner) at a particular cell is equal to the minimum of the sizes of the
21+
largest squares ending at the three adjacent cells plus 1.
22+
23+
We create a 2D integer array dp of size (r + 1) x (c + 1) where r is the number of rows in the input array and c is the
24+
size of each row. dp[i][j] stores the side length of the largest square ending at the cell matrix[i - 1][j - 1]. All
25+
elements of dp are initialized to 0.
26+
27+
![Solution 1](./images/solutions/maximal_square_solution_1.png)
28+
29+
We then use a nested loop to iterate over the input array. For each cell matrix[i - 1][j - 1], we check if the cell
30+
contains a 1. If it does, we update dp[i][j] to the minimum of the sizes of the largest squares ending at the three
31+
adjacent cells plus 1. We also update a variable max_side to store the maximum side length of the largest square we
32+
have found so far.
33+
34+
![Solution 2](./images/solutions/maximal_square_solution_2.png)
35+
![Solution 3](./images/solutions/maximal_square_solution_3.png)
36+
![Solution 4](./images/solutions/maximal_square_solution_4.png)
37+
![Solution 5](./images/solutions/maximal_square_solution_5.png)
38+
![Solution 6](./images/solutions/maximal_square_solution_6.png)
39+
![Solution 7](./images/solutions/maximal_square_solution_7.png)
40+
41+
At the end of the loop, max_side contains the side length of the largest square containing only 1's in the input array.
42+
The area of the square is max_side * max_side.
43+
44+
### Complexity analysis
45+
46+
#### Time Complexity
47+
48+
O(m * n) where m is the number of rows and n is the number of columns in the input array. We iterate over each cell once,
49+
and for each cell, we perform a constant amount of work.
50+
51+
#### Space Complexity
52+
53+
O(m * n) where m is the number of rows and n is the number of columns. We use a 2D array dp of size (m + 1) x (n + 1) to
54+
store the side length of the largest square ending at each cell.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import List
2+
3+
4+
def maximal_square(matrix: List[List[int]]) -> int:
5+
"""
6+
Returns the maximum area of a square containing only 1s in the 2D matrix
7+
Args:
8+
matrix(list): 2D matrix with 0s and 1s
9+
Returns:
10+
int: largest area of square with only 1s
11+
"""
12+
if not matrix:
13+
return 0
14+
15+
rows = len(matrix)
16+
cols = len(matrix[0])
17+
dp = [[0] * (cols + 1) for _ in range(rows + 1)]
18+
max_side = 0
19+
20+
for i in range(1, rows + 1):
21+
for j in range(1, cols + 1):
22+
if matrix[i - 1][j - 1] == 1:
23+
top = dp[i - 1][j]
24+
left = dp[i][j - 1]
25+
diag = dp[i - 1][j - 1]
26+
dp[i][j] = min(top, left, diag) + 1
27+
max_side = max(max_side, dp[i][j])
28+
29+
return max_side * max_side
74.2 KB
Loading
67.2 KB
Loading
75.7 KB
Loading
72.7 KB
Loading
66.3 KB
Loading
70.1 KB
Loading
68.1 KB
Loading

0 commit comments

Comments
 (0)