Hmm … "best way" is ever a fruitless question, because what is the measure for "best"?
Let a tile index be [x ; y]. Let the tiles covered by building n be from [xl,n ; yb,n] to [ xr,n; yt,n ], e.g. read it as from left / bottom corner to right / up corner. Then the separate distances between 2 buildings 1 and 2 for the both dimensions are
dx = min( | xl,1 - xr,2 | , | xr,1 - xl,2 | )
dy = min( | yb,1 - yt,2 | , | yt,1 - yb,2 | )
Both of the separate distances need to be 1 for directly adjacent buildings. A value of 2 means that 1 free tile is in-between them. Hence, if no more than 2 free tiles is allowed, both separate distances must be less than 4. (Notice that you may need to use a slightly more complex condition if diagonal distances need to be considered.)
Above solution requires AFAIS that the building do not overlap, or else false positives may occur if one building is really big compared to the other, so checking whether the tiles under the placeable building are free should be done already simply by checking each tile in [xl,2 ; yb,2] to [ xr,2; yt,2 ] for coverage.
You can restrict the search over all already placed buildings (if needed) by e.g. using a spatial partitioning scheme.