Quick Overview

Choose at most one global blocker removal to minimize the time for all grid targets to receive signals, with deterministic tie-breaking.

Choose One Blocker Removal for the Fastest Grid Signals

Company: Google

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

A rectangular city grid contains sources `S`, blockers `B`, targets `T`, and empty cells `.`. At time zero, every source begins sending a signal. A signal spreads one cell per unit of time in the four orthogonal directions and cannot enter a blocker. Before propagation begins, you may remove at most one blocker, turning that one cell into an empty cell. Choose the removal, if any, that minimizes the time until every target receives a signal. ### Input - `grid`: an array of equal-length strings using the four cell symbols above. ### Output Return `[minimum_time, removed_row, removed_column]` using zero-based coordinates and the following deterministic practice conventions: - If removing nothing attains the minimum time, prefer that choice and return `-1` for both coordinates. - Otherwise, among equally good removals, choose the smallest row, then the smallest column. - If no permitted choice reaches every target, return `[-1, -1, -1]`. ### Constraints and Edge Cases - For this practice version, the grid has between `1` and `30` rows and between `1` and `30` columns. - There is at most one removed blocker in the entire grid; different signal paths cannot each remove their own blocker. - Removal happens before time zero and has no propagation-time cost. - Signals may pass through sources, targets, and empty cells, including the removed blocker. - If there are no targets, return `[0, -1, -1]`. - If targets exist but there are no sources, return `[-1, -1, -1]`. ### Example 1 ```text grid = ["SBT"] output = [2, 0, 1] ``` Removing the middle blocker allows the signal to reach the target in two steps. ### Example 2 ```text grid = ["SBT", "BBB", "TBS"] output = [-1, -1, -1] ``` One removal can connect a source to one of the targets, but no single shared removal makes both targets reachable.

Overview: Choose at most one global blocker removal to minimize the time for all grid targets to receive signals, with deterministic tie-breaking.

Read the full Google Software Engineer interview experience this question came from

A rectangular city grid contains sources `S`, blockers `B`, targets `T`, and empty cells `.`. At time zero, every source begins sending a signal. A signal spreads one cell per unit of time in the four orthogonal directions and cannot enter a blocker. Before propagation begins, you may remove at most one blocker, turning that one cell into an empty cell. Choose the removal, if any, that minimizes the time until every target receives a signal. ### Input - `grid`: an array of equal-length strings using the four cell symbols above. ### Output Return `[minimum_time, removed_row, removed_column]` using zero-based coordinates and the following deterministic practice conventions: - If removing nothing attains the minimum time, prefer that choice and return `-1` for both coordinates. - Otherwise, among equally good removals, choose the smallest row, then the smallest column. - If no permitted choice reaches every target, return `[-1, -1, -1]`. ### Constraints and Edge Cases - For this practice version, the grid has between `1` and `30` rows and between `1` and `30` columns. - There is at most one removed blocker in the entire grid; different signal paths cannot each remove their own blocker. - Removal happens before time zero and has no propagation-time cost. - Signals may pass through sources, targets, and empty cells, including the removed blocker. - If there are no targets, return `[0, -1, -1]`. - If targets exist but there are no sources, return `[-1, -1, -1]`. ### Example 1 ```text grid = ["SBT"] output = [2, 0, 1] ``` Removing the middle blocker allows the signal to reach the target in two steps. ### Example 2 ```text grid = ["SBT", "BBB", "TBS"] output = [-1, -1, -1] ``` One removal can connect a source to one of the targets, but no single shared removal makes both targets reachable.

Constraints

  • The rectangular grid has 1 through 30 rows and columns, with equal-length strings using only S, B, T and period.
  • All sources propagate simultaneously at time zero; one orthogonal step costs one unit and every non-blocker cell is traversable.
  • At most one blocker is removed globally before propagation, with no removal-time cost; all signal paths share that fixed choice.
  • Minimize the maximum target first-arrival time. Prefer no removal on an optimal tie, then the smallest removal row and column.
  • No targets returns [0,-1,-1]. No permitted choice reaching all targets returns [-1,-1,-1], including targets with no source.

Examples

Input: (['SBT'],)

Expected Output: [2, 0, 1]

Explanation: Published sample 1: removing the middle blocker creates the two-step route.

Input: (['SBT', 'BBB', 'TBS'],)

Expected Output: [-1, -1, -1]

Explanation: Published sample 2: the two targets require incompatible removals; no single globally shared blocker suffices.

Community answers

Answer by chandanagrawal23

#include using namespace std; int m, n; vector> sources; vector> targets; int bfs(vector& grid, int removeR, int removeC) { vector> dist(m, vector(n, -1)); queue> q; for(auto [r, c] : sources) { dist[r][c] = 0; q.push({r, c}); } int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; while(!q.empty()) { auto [r, c] = q.front(); q.pop(); for(int k = 0; k < 4; k++) { int nr = r + dr[k]; int nc = c + dc[k]; if(nr < 0 || nr >= m || nc < 0 || nc >= n) continue; if(dist[nr][nc] != -1) continue; if(grid[nr][nc] == 'B' && !(nr == removeR && nc == removeC)) continue; dist[nr][nc] = dist[r][c] + 1; q.push({nr, nc}); } } int maxTime = 0; for(auto [r, c] : targets) { if(dist[r][c] == -1) return INT_MAX; maxTime = max(maxTime, dist[r][c]); } return maxTime; } vector solve(vector& grid) { m = grid.size(); n = grid[0].size(); vector> blockers; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(grid[i][j] == 'S') sources.push_back({i, j}); else if(grid[i][j] == 'T') targets.push_back({i, j}); else if(grid[i][j] == 'B') blockers.push_back({i, j}); } } if(targets.empty()) return {0, -1, -1}; if(sources.empty()) return {-1, -1, -1}; int bestTime = bfs(grid, -1, -1); int bestR = -1; int bestC = -1; for(auto [r, c] : blockers) { int time = bfs(grid, r, c); if(time < bestTime) { bestTime = time; bestR = r; bestC = c; } } if(bestTime == INT_MAX) return {-1, -1, -1}; return {bestTime, bestR, bestC}; } int main() { vector grid = { "SBT" }; vector ans = solve(grid); cout << ans[0] << " " << ans[

Loading coding console...

Show the approach

Approach

List all sources, targets and blockers, recording blockers in row-major order. If there are no targets, return the specified zero-time no-removal answer; if targets exist but there is no source, return the impossible answer.

Evaluate removing nothing, followed by removing each single blocker in that fixed order. For each choice, run a fresh multi-source breadth-first search with every source in the initial queue at distance zero. Treat a blocker as traversable only when it is the one selected for this evaluation. Mark a cell when it enters the queue, so it is reached only once. After propagation, reject the choice if any target is unseen; otherwise its completion time is the maximum target distance.

Multi-source breadth-first search computes the shortest distance to any initial source because all distance-zero sources enter before later layers. It therefore gives every target's first signal arrival under the fixed global removal. Taking the maximum is precisely when all targets have arrived. Evaluating every allowed choice makes the best finite completion time globally optimal. The algorithm never gives different paths separate removal budgets.

Initialize the answer with the no-removal result. Replace it only with a strictly smaller finite time, or with the first finite time when the current answer is impossible. Thus an equal no-removal time wins automatically, and equal successful removals retain the earliest row and column. If every evaluation fails, the original [-1,-1,-1] answer remains.

With R rows, C columns and B blockers, one search takes O(RC) time and space. There are B+1 choices, so total time is O((B+1)RC), with O(RC) live auxiliary storage. At the 30-by-30 limit there are at most 900 cells and at most 901 nominal choices, giving fewer than 811000 cell positions across the simple upper bound before constant-size neighbor work. Any finite path has at most 899 steps and all integers fit signed 32 bits. The grid is never changed; each evaluation uses a selected-coordinate exception.

Time complexity:
O((B+1)*R*C) for B blockers and an R-by-C grid.
Space complexity:
O(R*C) live auxiliary storage for sources, targets, blockers, distances and a queue.