当前位置: 代码迷 >> 综合 >> Leetcode 317. Shortest Distance from All Buildings (python+cpp)
  详细解决方案

Leetcode 317. Shortest Distance from All Buildings (python+cpp)

热度:65   发布时间:2023-11-26 06:48:00.0

Leetcode 317. Shortest Distance from All Buildings

  • 题目
  • 解法1:BFS
  • 解法2:
  • 二刷C++版本

题目

在这里插入图片描述

解法1:BFS

brutal force的从每一个空地出发,找与building的最短距离之和

class Solution:def shortestDistance(self, grid: List[List[int]]) -> int:def helper(i,j):visited = set()buildings = set()q = collections.deque()q.append((i,j,0))visited.add((i,j))total_step = 0dirs = [[0,1],[0,-1],[-1,0],[1,0]]while q:i,j,step = q.popleft()if grid[i][j] == 1 and (i,j) not in buildings:total_step += stepbuildings.add((i,j))if len(buildings) == num_buildings:breakif grid[i][j]!=1:for d in dirs:x = i+d[0]y = j+d[1]if 0<=x<m and 0<=y<n and (x,y) not in visited and grid[x][y]!=2:q.append((x,y,step+1))visited.add((x,y))return total_step if len(buildings)==num_buildings else -1m,n = len(grid),len(grid[0])num_buildings = 0for i in range(m):for j in range(n):if grid[i][j] == 1:num_buildings += 1min_step = float('inf')for i in range(m):for j in range(n):if grid[i][j] == 0:total_step = helper(i,j)if total_step!=-1 and min_step>total_step:min_step = total_stepreturn min_step if min_step!=float('inf') else -1

解法2:

根据题意来看,building数肯定是比空地数要少很多的,所以可以反向从building出发找每块空地与这个building的距离,然后对于每个building都做同样的事,将结果叠加找最小值

class Solution:def shortestDistance(self, grid: List[List[int]]) -> int:def bfs(i,j):visited = [[False]*n for _ in range(m)]q = collections.deque()q.append((i,j,1))dirs = [[0,1],[0,-1],[-1,0],[1,0]]while q:i,j,dis = q.popleft()for d in dirs:x = i+d[0]y = j+d[1]if 0<=x<m and 0<=y<n and not visited[x][y] and grid[x][y]==0:distance[x][y] += disreach_num[x][y] += 1q.append((x,y,dis+1))visited[x][y] = Truem,n = len(grid),len(grid[0])distance = [[0]*n for _ in range(m)]reach_num = [[0]*n for _ in range(m)]building_num = 0for i in range(m):for j in range(n):if grid[i][j] == 1:bfs(i,j)building_num += 1min_dist = float('inf')for i in range(m):for j in range(n):if grid[i][j]==0 and reach_num[i][j]==building_num:min_dist = min(min_dist,distance[i][j])return min_dist if min_dist!=float('inf') else -1

二刷C++版本

class Solution {
    
public:int shortestDistance(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();// distance matrix for holding the sum of distance from current position// to all buildingsvector<vector<int>> dist(m,vector<int>(n,0));// matrix to check how many buildings can be reached from current positionvector<vector<int>> reached(m,vector<int>(n,0));// for every building position, we do bfs to find the minimum distance from// current building to every empty land. Update the dist and reached matrixint num_building = 0;for(int i=0;i<m;i++){
    for(int j=0;j<n;j++){
    if(grid[i][j] == 1){
    bfs(grid,dist,reached,i,j);num_building += 1;}}}// traverse dist and reached matrix, looking for the answerint ans = INT_MAX;for(int i=0;i<m;i++){
    for(int j=0;j<n;j++){
    if(grid[i][j] == 0 && reached[i][j] == num_building){
    ans = min(ans,dist[i][j]);}}}return ans == INT_MAX ? -1 : ans;}void bfs(const vector<vector<int>>& grid, vector<vector<int>>& dist, vector<vector<int>>& reached, int i, int j){
    queue<vector<int>> q;q.push({
    i,j,0});vector<vector<int>> visited(grid.size(),vector<int>(grid[0].size(),0));visited[i][j] = 1;vector<vector<int>> dirs{
    {
    0,1},{
    0,-1},{
    1,0},{
    -1,0}};int x,y,next_x,next_y,step;while(!q.empty()){
    x = q.front()[0];y = q.front()[1];step = q.front()[2];q.pop();for(auto d : dirs){
    next_x = x + d[0];next_y = y + d[1];if(next_x >= 0 && next_x < grid.size() && next_y >= 0 && next_y < grid[0].size() && visited[next_x][next_y] == 0 && grid[next_x][next_y] == 0){
    q.push({
    next_x,next_y,step+1});visited[next_x][next_y] = 1;dist[next_x][next_y] += step + 1;reached[next_x][next_y] += 1;}}}}
};