Nothing magic here. Just BFS, but - BFS from land is not a good idea - BFS from Buildings.
Lesson learnt: reverse thinking helps!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: int shortestDistance(vector<vector<int>>& grid) { int ret = 0; // Get dimension int h = grid.size(); if(!h) return ret; int w = grid[0].size(); if(!w) return ret; // Get all buildings typedef pair<int, int> Loc; vector<Loc> buildings; for(int i = 0; i < h; i ++) for(int j = 0; j < w; j ++) { if(grid[i][j] == 1) { buildings.push_back(Loc(i, j)); } } size_t n = buildings.size(); unsigned long long FullMask = ((unsigned long long)1 << n) - 1; // struct Rec { unsigned long long mask; int ttl; }; ret = INT_MAX; vector<vector<Rec>> inf(h, vector<Rec>(w)); for(int i = 0; i < buildings.size(); i ++) { Loc &b = buildings[i]; queue<Loc> q; vector<vector<bool>> visited(h, vector<bool>(w, false)); vector<vector<bool>> inq(h, vector<bool>(w, false)); q.push(b); visited[b.first][b.second] = inq[b.first][b.second] = true; int layerCnt = 1, layer = 0; while(!q.empty()) { Loc c = q.front(); q.pop(); visited[c.first][c.second] = true; // Mark if(grid[c.first][c.second] == 0) { inf[c.first][c.second].mask |= (unsigned long long)1 << i; inf[c.first][c.second].ttl += layer; if(i == (buildings.size() - 1)) { if(inf[c.first][c.second].mask == FullMask) ret = min(ret, inf[c.first][c.second].ttl); } } int dx[] = {-1, 0, 1, 0}; int dy[] = { 0, -1, 0, 1}; for(int k = 0; k < 4; k ++) { Loc nc(c.first + dy[k], c.second + dx[k]); if((nc.first >= 0 && nc.first < h && nc.second >= 0 && nc.second < w) && (!grid[nc.first][nc.second] && !visited[nc.first][nc.second] && (!inq[nc.first][nc.second])) ) { q.push(nc); inq[nc.first][nc.second] = true; } } layerCnt --; if(!layerCnt) { layerCnt = q.size(); layer ++; } } } return ret == INT_MAX? -1 : ret; } };
Yes there are several optimizations feasible above.