
Problem Statement
In this scenario, you are provided with an m x n
matrix populated solely with binary integers (i.e., 0
s and 1
s). Your task is to determine how many distinct "corner rectangles" can be formed in the grid. Each corner rectangle is defined by four distinct 1
s that form the vertices of an axis-aligned rectangle. Notably, it's essential for the rectangle to align with the axes of the grid, meaning that only horizontal and vertical alignments are permissible, with diagonally aligned 1
s not constituting the corners of a valid rectangle.
Examples
Example 1
Input:
grid = [[1,0,0,1,0],[0,0,1,0,1],[0,0,0,1,0],[1,0,1,0,1]]
Output:
1
Explanation:
There is only one corner rectangle, with corners grid[1][2], grid[1][4], grid[3][2], grid[3][4].
Example 2
Input:
grid = [[1,1,1],[1,1,1],[1,1,1]]
Output:
9
Explanation:
There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle.
Example 3
Input:
grid = [[1,1,1,1]]
Output:
0
Explanation:
Rectangles must have four distinct corners.
Constraints
m == grid.length
n == grid[i].length
1 <= m, n <= 200
grid[i][j]
is either0
or1
.- The number of
1
's in the grid is in the range[1, 6000]
.
Approach and Intuition
To solve this problem, one needs to adopt a systematic approach to count how many rectangles can be formed given the constraints:
Identify Pairs:
- Conceptualize the matrix in terms of rows and columns. The idea is to identify all pairs of
1
s in every row. These pairs will serve as potential top or bottom sides of the corner rectangles.
- Conceptualize the matrix in terms of rows and columns. The idea is to identify all pairs of
Count Matching Pairs:
- For every pair of
1
s identified in the above step, see if the same pair of columns has1
s in other rows too. Every time you find such a match in another row, a potential rectangle is identified.
- For every pair of
Calculate Rectangle Count:
- To avoid double-counting rectangles, focus only on identifying top sides and count every compatible bottom side found in any row below.
- The rectangles formed by pairs
(col1, col2)
from different rowsrow1
androw2
are distinct rectangles. Keep a counter that sums up these valid rectangles.
Optimize Using Pre-Computed Values:
- Use a hashmap or an equivalent structure to keep track of pairs and their occurrences across different row checks. This helps in quickly determining potential rectangles without redundant computations.
Example Explorations:
Example 1:
- The grid configuration
[[1,0,0,1,0],[0,0,1,0,1],[0,0,0,1,0],[1,0,1,0,1]]
results in one possible rectangle. This calculation aligns with the explanation and matches real grid visualization, confirming the approach.
- The grid configuration
Example 2:
- A fully populated grid with rows of
1
s such as[[1,1,1],[1,1,1],[1,1,1]]
provides multiple combination possibilities across rows, confirming the importance of systematic pairwise checks and counting.
- A fully populated grid with rows of
Example 3:
- The provided row of
[[1,1,1,1]]
reminds us of the non-existence of rectangles in single-row scenarios regardless of the number of1
s, underscoring the necessity of having at least two rows for a rectangle to form.
- The provided row of
Through these analyses, one can grasp how different grid configurations impact the potential for forming rectangles and adapt the counting methodology appropriately within the given constraints.
Solutions
- Java
class ShapeFinder {
public int countRectangles(int[][] board) {
List<List<Integer>> activeRows = new ArrayList<>();
int countOnes = 0;
for (int row = 0; row < board.length; ++row) {
activeRows.add(new ArrayList());
for (int col = 0; col < board[row].length; ++col)
if (board[row][col] == 1) {
activeRows.get(row).add(col);
countOnes++;
}
}
int threshold = (int) Math.sqrt(countOnes);
int result = 0;
Map<Integer, Integer> pairCount = new HashMap<>();
for (int row = 0; row < board.length; ++row) {
if (activeRows.get(row).size() >= threshold) {
Set<Integer> currentSet = new HashSet(activeRows.get(row));
for (int nextRow = 0; nextRow < board.length; ++nextRow) {
if (nextRow <= row && activeRows.get(nextRow).size() >= threshold) {
continue;
}
int matches = 0;
for (int item: activeRows.get(nextRow)) {
if (currentSet.contains(item)) {
matches++;
}
}
result += matches * (matches - 1) / 2;
}
} else {
for (int first = 0; first < activeRows.get(row).size(); ++first) {
int col1 = activeRows.get(row).get(first);
for (int second = first + 1; second < activeRows.get(row).size(); ++second) {
int col2 = activeRows.get(row).get(second);
int code = 200 * col1 + col2;
int previousCount = pairCount.getOrDefault(code, 0);
result += previousCount;
pairCount.put(code, previousCount + 1);
}
}
}
}
return result;
}
}
The Java solution provided aims to count the number of corner rectangles formed in a 2D binary matrix, termed as board
, where only cells with a value of 1 can form the corners of a rectangle. The logic behind the solution involves using Data Structures like Lists, Sets, and Maps to efficiently track and calculate the potential rectangles. Here's how the solution works:
- A
List<List<Integer>>
namedactiveRows
is created to store columns for each row where the value is 1, providing quick access to potential corners from each row. - The variable
countOnes
keeps track of the total number of 1s in the board for determining thethreshold
, which is set to the square root ofcountOnes
and used for an optimization technique. - Two main loops are iterated over each row, and within these two approaches are considered based on the size of
activeRows
compared to thethreshold
:- If the size of
activeRows
for a row is greater than or equal to the threshold, the algorithm utilizes a Set to store unique columns of current row which have 1s. An inner loop checks for rows below the current one if they meet the size criterion and counts overlaps of columns with 1s, indicating potential rectangle top corners. The number of ways to select two points from the matches gives the number of rectangle tops. - If the row does not meet the threshold criteria, a more direct comparison using nested loops for pairs of 1s in the same row is employed. Each unique pair (denoted by column indices of the 1s) stores and builds up a count in a
Map<Integer, Integer>
, representing possible rectangle tops from earlier occurrences.
- If the size of
- The stored values are utilized to compute and consolidate counts of detected rectangles, resulting in the final count after all possibilities are explored across rows.
Given this strategy, the solution operates efficiently for sparse boards, by directing computation focus using the threshold and mapping technique to reduce redundant checks and leveraging space-time trade-offs. Adjustments or understanding of the variable 'threshold' may be necessary based on different board densities or distributions of 1s.
No comments yet.