【Leetcode】317. Shortest Distance from All Buildings

这篇博客介绍了如何运用广度优先搜索(BFS)算法解决一个二维矩阵中寻找建造房屋位置的问题,使得房屋到所有建筑物的路径长度之和最小。题目中矩阵包含0(空地)、1(建筑)和2(障碍物),算法需要遍历每个建筑并统计可达空地的最短距离,最后找出最短总距离。如果无法找到合适的房屋位置,则返回-1。博客给出了详细的BFS实现代码,并分析了时间复杂度为O(kmn),其中k为建筑数量,m和n为矩阵的尺寸。
摘要由CSDN通过智能技术生成

题目地址:

https://leetcode.com/problems/shortest-distance-from-all-buildings/

给定一个二维矩阵,只含 0 , 1 , 2 0,1,2 0,1,2 0 0 0代表空地, 1 1 1代表建筑, 2 2 2代表障碍物。要求在一个空地建个房屋,使得房屋到所有建筑物的路径长度之和达到最小。路径的每一步只能向上下左右走,并且只能走到空地上。如果存在房屋的建造方案,则返回最短路径长度总和;否则返回 − 1 -1 1

思路是BFS。可以从每个建筑物出发,遍历一下其所能到达的空地,并累加该空地与之的路径距离。遍历的同时要注意,如果一个某个空地这个建筑物到不了,那么说明这个空地是不能建房屋的,最后统计的时候要把这个空地排除在外。代码如下:

class Solution {
 public:
  using PII = pair<int, int>;
#define x first
#define y second
  int shortestDistance(vector<vector<int>>& g) {
    int m = g.size(), n = g[0].size();
    int sum_dist[m][n];
    memset(sum_dist, 0, sizeof sum_dist);
    auto bfs = [&](int x, int y) {
      bool vis[m][n];
      memset(vis, 0, sizeof vis);
      vis[x][y] = true;
      queue<PII> q;
      q.push({x, y});
      int step = 0;
      while (q.size()) {
        step++;
        for (int _ = q.size(); _; _--) {
          auto p = q.front(); q.pop();
          int x = p.x, y = p.y;
          static int d[] = {-1, 0, 1, 0, -1};
          for (int k = 0; k < 4; k++) {
            int nx = x + d[k], ny = y + d[k + 1];
            if (0 <= nx && nx < m && 0 <= ny && ny < n && !vis[nx][ny] &&
                !g[nx][ny]) {
              vis[nx][ny] = true;
              q.push({nx, ny});
              if (~sum_dist[nx][ny]) sum_dist[nx][ny] += step;
            }
          }
        }
      }

	  // 如果有空地不能到达,则这个空地不能参与统计
      for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
          if (!g[i][j] && !vis[i][j]) sum_dist[i][j] = -1;
    };
    
    for (int i = 0; i < m; i++)
      for (int j = 0; j < n; j++)
        if (g[i][j] == 1) bfs(i, j);

    int res = INT_MAX;
    for (int i = 0; i < m; i++)
      for (int j = 0; j < n; j++)
        if (!g[i][j] && ~sum_dist[i][j]) res = min(res, sum_dist[i][j]);

    return res == INT_MAX ? -1 : res;
  }
};

时间复杂度 O ( k m n ) O(kmn) O(kmn) k k k为建筑物数量,空间 O ( m n ) O(mn) O(mn)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值