zoukankan      html  css  js  c++  java
  • LeetCode "Shortest Distance from All Buildings"

    Nothing magic here. Just BFS, but - BFS from land is not a good idea - BFS from Buildings.

    Lesson learnt: reverse thinking helps!

    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;
        }
    };
    View Code

    Yes there are several optimizations feasible above.

  • 相关阅读:
    (转)多线程同步event
    初始化列表中成员列出的顺序和它们在类中声明的顺序相同
    确定基类有虚析构函数
    (转)list::splice()函数详解
    MANIFEST.MF文件的格式
    NIO入门了解Buffer
    Failed to load class "org.slf4j.impl.StaticLoggerB
    线程挂起自己,让出CPU
    database如何管理超过4GB的文件
    线程同步(C# 编程指南)
  • 原文地址:https://www.cnblogs.com/tonix/p/5065466.html
Copyright © 2011-2022 走看看