You are given a positive integer n, representing an n x n city. You are also given a 2D grid buildings, where buildings[i] = [x, y] denotes a unique building located at coordinates [x, y].
A building is covered if there is at least one building in all four directions: left, right, above, and below.
Return the number of covered buildings.
Example 1:

Input: n = 3, buildings = [[1,2],[2,2],[3,2],[2,1],[2,3]]
Output: 1
Explanation:
[2,2] is covered as it has at least one building:
[1,2])[3,2])[2,1])[2,3])Example 2:

Input: n = 3, buildings = [[1,1],[1,2],[2,1],[2,2]]
Output: 0
Explanation:
Example 3:

Input: n = 5, buildings = [[1,3],[3,2],[3,3],[3,5],[5,3]]
Output: 1
Explanation:
[3,3] is covered as it has at least one building:
[1,3])[5,3])[3,2])[3,5])Constraints:
2 <= n <= 1051 <= buildings.length <= 105 buildings[i] = [x, y]1 <= x, y <= nbuildings are unique.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're given buildings and need to figure out how many are completely covered by others. The brute force method will check every building against every other building to see if one fully covers the other.
Here's how the algorithm would work step-by-step:
def count_covered_buildings_brute_force(buildings):
number_of_buildings = len(buildings)
covered_buildings_count = 0
covered_status = [False] * number_of_buildings
for current_building_index in range(number_of_buildings):
# Iterate through all other buildings
for other_building_index in range(number_of_buildings):
# Avoid comparing a building to itself
if current_building_index == other_building_index:
continue
current_building_start = buildings[current_building_index][0]
current_building_end = buildings[current_building_index][1]
other_building_start = buildings[other_building_index][0]
other_building_end = buildings[other_building_index][1]
# Check if the current building is covered
if (other_building_start <= current_building_start and\
other_building_end >= current_building_end):
# Mark current building as covered
covered_status[current_building_index] = True
# No need to check other buildings
break
# Count the number of covered buildings
for status in covered_status:
if status:
covered_buildings_count += 1
return covered_buildings_countThe core idea is to think of each building as casting a shadow, and we want to find the total length of the ground covered by these shadows. Instead of checking each tiny piece of ground, we'll focus on the start and end points of these shadows, sorting them to process them in the correct order.
Here's how the algorithm would work step-by-step:
def count_covered_buildings(buildings):
important_points = []
for start, end, height in buildings:
important_points.append((start, height, 1)) # 1 marks start
important_points.append((end, height, -1)) # -1 marks end
important_points.sort(key=lambda x: x[0])
active_heights = []
total_covered_area = 0
previous_location = 0
for location, height, point_type in important_points:
# Calculate covered area since last point
if active_heights:
max_active_height = max(active_heights)
total_covered_area += max_active_height * (location - previous_location)
# Update active heights based on point type
if point_type == 1:
# Starting point: add height to active heights.
active_heights.append(height)
else:
# Ending point: remove height from active heights.
active_heights.remove(height)
# Removing the current height from active_heights
previous_location = location
return total_covered_area| Case | How to Handle |
|---|---|
| buildings is null or empty | Return 0 because there are no buildings to cover |
| buildings contains only one building | Return 0 because at least two buildings are required to form a covered range |
| buildings array contains very large numbers | Ensure the data type used to store heights or positions can accommodate these large numbers, preventing potential overflow |
| buildings array contains duplicate positions | Handle duplicates by considering only the building with the maximum height at that position to maximize coverage |
| buildings are already completely covered by existing ranges | The algorithm should correctly return 0 if all buildings are already within the covered ranges |
| buildings array contains overlapping ranges | The algorithm should merge overlapping ranges into a single, larger range to accurately count the covered buildings |
| buildings array size approaches the maximum allowed limit | Optimize for space complexity to prevent memory exhaustion when processing a very large number of buildings |
| Integer overflow when calculating the covered length | Use a data type with a larger range, such as long, to store the length of the covered range. |