LeetCode Challenge Day 87 — 3531. Count Covered Buildings
Nitin Ahirwal / December 11, 2025
Hey folks 👋
This is Day 87 of my LeetCode streak 🚀
Today's problem is 3531. Count Covered Buildings — a deceptively simple geometry problem once you see the boundary pattern.
📌 Problem Statement
You're given:
- A positive integer
n(size of the city gridn × n) - An array
buildingswhere each entry[x, y]represents a unique building
A building at (x, y) is covered if there exists:
- A building left of it
- A building right of it
- A building above it
- A building below it
Return the number of such covered buildings.
💡 Intuition
You don't need to simulate the grid.
A building (x, y) is covered if:
In its row:
- There is a building with
y' < y→ left - There is a building with
y' > y→ right
In its column:
- There is a building with
x' < x→ above - There is a building with
x' > x→ below
This becomes a range boundary problem:
- Track
minYandmaxYfor each row - Track
minXandmaxXfor each column
A building is covered iff:
rowMin[x] < y < rowMax[x]
colMin[y] < x < colMax[y]
That's the key insight.
🔑 Approach
-
Create four maps:
rowMin[x],rowMax[x]colMin[y],colMax[y]
-
Traverse all buildings once to fill these maps.
-
For each building:
- Check if it lies strictly between the min/max of its row and column.
-
Count it if all four directional requirements are met.
Efficient and elegant.
⏱️ Complexity Analysis
-
Time Complexity:
O(m)wherem = buildings.length -
Space Complexity:
O(m)for storing row and column boundaries
🧑💻 Code (JavaScript)
/**
* @param {number} n
* @param {number[][]} buildings
* @return {number}
*/
var countCoveredBuildings = function(n, buildings) {
const rowMin = new Map(); // row x -> min y
const rowMax = new Map(); // row x -> max y
const colMin = new Map(); // col y -> min x
const colMax = new Map(); // col y -> max x
for (const [x, y] of buildings) {
if (!rowMin.has(x) || y < rowMin.get(x)) rowMin.set(x, y);
if (!rowMax.has(x) || y > rowMax.get(x)) rowMax.set(x, y);
if (!colMin.has(y) || x < colMin.get(y)) colMin.set(y, x);
if (!colMax.has(y) || x > colMax.get(y)) colMax.set(y, x);
}
let count = 0;
for (const [x, y] of buildings) {
const leftExists = rowMin.get(x) < y;
const rightExists = rowMax.get(x) > y;
const aboveExists = colMin.get(y) < x;
const belowExists = colMax.get(y) > x;
if (leftExists && rightExists && aboveExists && belowExists) {
count++;
}
}
return count;
};
🎯 Reflection
This problem highlights how:
-
Avoiding 2D grid simulation can save massive time
-
Tracking min/max boundaries turns spatial reasoning into simple comparisons
-
Clean preprocessing leads to clean logic
That's it for Day 87 of my LeetCode challenge!
Streak going strong 🔥
Happy Coding 👨💻