I store all buildings by row and by column and only need to know, for each row x, the smallest and largest column index y present and, for each column y, the smallest and largest row index x present. A building at (x,y) is covered iff there exists at least one building strictly above (some x' < x in same column), strictly below (x' > x in same column), strictly left (y' < y in same row) and strictly right (y' > y in same row). That is exactly the condition min_row_y < y < max_row_y and min_col_x < x < max_col_x. I precompute those mins/maxs for every row and column in O(m) time (m = number of buildings) and then count how many buildings satisfy both strict inequalities.
class Solution:
def countCoveredBuildings(self, n: int, buildings: List[List[int]]) -> int: