LeetCode 317. Shortest Distance from All Buildings(最短建筑距离)
2016-04-23 09:18
573 查看
原题网址:https://leetcode.com/problems/shortest-distance-from-all-buildings/
You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2,
where:
Each 0 marks an empty land which you can pass by freely.
Each 1 marks a building which you cannot pass through.
Each 2 marks an obstacle which you cannot pass through.
For example, given three buildings at
and an obstacle at
The point
of 3+3+1=7 is minimal. So return 7.
Note:
There will be at least one building. If it is not possible to build such house according to the above rules, return -1.
方法:从每一栋建筑出发,广度优先搜索,更新该建筑到各块空地的距离。另外一个诀窍就是如果有两栋建筑之间不连通,则直接返回-1。
另一种实现:
You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2,
where:
Each 0 marks an empty land which you can pass by freely.
Each 1 marks a building which you cannot pass through.
Each 2 marks an obstacle which you cannot pass through.
For example, given three buildings at
(0,0),
(0,4),
(2,2),
and an obstacle at
(0,2):
1 - 0 - 2 - 0 - 1 | | | | | 0 - 0 - 0 - 0 - 0 | | | | | 0 - 0 - 1 - 0 - 0
The point
(1,2)is an ideal empty land to build a house, as the total travel distance
of 3+3+1=7 is minimal. So return 7.
Note:
There will be at least one building. If it is not possible to build such house according to the above rules, return -1.
方法:从每一栋建筑出发,广度优先搜索,更新该建筑到各块空地的距离。另外一个诀窍就是如果有两栋建筑之间不连通,则直接返回-1。
public class Solution { private int[] r = {-1, 1, 0, 0}; private int[] c = {0, 0, -1, 1}; private boolean update(int[][] grid, int buildings, int row, int col, int[][] reach, int[][] distance) { boolean[][] visited = new boolean[grid.length][grid[0].length]; Position position = new Position(row, col, 0); Position tail = position; visited[row][col] = true; int reached = 1; while (position != null) { distance[position.row][position.col] += position.distance; for(int i=0; i<4; i++) { int y = position.row + r[i]; int x = position.col + c[i]; if (y >= 0 && y < grid.length && x >= 0 && x < grid[y].length && !visited[y][x]) { visited[y][x] = true; if (grid[y][x] == 1) { reached ++; } else if (grid[y][x] == 0) { reach[y][x] ++; tail.next = new Position(y, x, position.distance + 1); tail = tail.next; } } } position = position.next; } // System.out.printf("row=%d, col=%d, reached=%d, buildings=%d\n", row, col, reached, buildings); return reached == buildings; } public int shortestDistance(int[][] grid) { int[][] distance = new int[grid.length][grid[0].length]; int[][] reach = new int[grid.length][grid[0].length]; int buildings = 0; for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j] == 1) buildings ++; } } for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j] == 1) { if (!update(grid, buildings, i, j, reach, distance)) return -1; } } } // System.out.println(); // for(int i=0; i<grid.length; i++) { // for(int j=0; j<grid[i].length; j++) System.out.print(distance[i][j]+","); // System.out.println(); // } int min = -1; for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j] == 0 && reach[i][j] == buildings && (min == -1 || distance[i][j] < min)) min = distance[i][j]; } } return min; } } class Position { int row, col; int distance; Position next; Position(int row, int col, int distance) { this.row = row; this.col = col; this.distance = distance; } }
另一种实现:
public class Solution { private int[] ro = {-1, 1, 0, 0}; private int[] co = {0, 0, -1, 1}; private int br, bc; private int go(int[][] grid, boolean[][] visit, int row, int col) { int count = 0; if (visit[row][col] || grid[row][col] == 2) return 0; if (grid[row][col] == 1) { visit[row][col] = true; return 1; } visit[row][col] = true; for(int i=0; i<4; i++) { int r = row + ro[i]; int c = col + co[i]; if (r>=0 && r<grid.length && c>=0 && c<grid[r].length) count += go(grid, visit, r, c); } return count; } private int buildings(int[][] grid) { int count = 0; for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j] == 1) { br = i; bc = j; count ++; } } } return count; } private void calc(int[][] grid, int[][] total, int[][] reach, int row, int col) { int[][] dist = new int[grid.length][grid[0].length]; LinkedList<Step> queue = new LinkedList<>(); queue.add(new Step(row, col, 0)); while (!queue.isEmpty()) { Step step = queue.remove(); for(int i=0; i<4; i++) { int r = step.row+ro[i]; int c = step.col+co[i]; if (r>=0 && r<grid.length && c>=0 && c<grid[r].length && dist[r][c]==0 && grid[r][c]==0) { dist[r][c] = step.step+1; total[r][c] += dist[r][c]; reach[r][c] ++; queue.add(new Step(r, c, step.step+1)); } } } } public int shortestDistance(int[][] grid) { int buildings = buildings(grid); int go = 0; boolean[][] visit = new boolean[grid.length][grid[0].length]; for(int i=0; i<4; i++) { int r = br+ro[i]; int c = bc+co[i]; if (r>=0 && r<grid.length && c>=0 && c<grid[r].length && grid[r][c]==0) { go += go(grid, visit, r, c); } } if (buildings != go) return -1; int[][] total = new int[grid.length][grid[0].length]; int[][] reach = new int[grid.length][grid[0].length]; for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j]==1) { calc(grid, total, reach, i, j); } } } int min = Integer.MAX_VALUE; for(int i=0; i<grid.length; i++) { for(int j=0; j<grid[i].length; j++) { if (grid[i][j]==0 && reach[i][j]==buildings) min = Math.min(min, total[i][j]); } } return min; } } class Step { int row, col, step; Step(int row, int col, int step) { this.row = row; this.col = col; this.step = step; } }
相关文章推荐
- iOS应用开发中对UIImage进行截取和缩放的方法详解
- Timer,TimerTask,TaskQueue,TimerThread原理关系图
- 掌握 Dojo 工具包,第 5 部分: Dojo 的 UI 组件库 - Dijit
- uinty3d Auto Layout(自动布局)
- About Quartz.Net Build the environment and some example
- 基于UICollectionView的无限轮播器(封装)
- storyboard之 prepareForSegue:sender:
- git——xuexi xin de ti hui (TODO..)
- 第四天:高级UI控件
- uitextfield placeholder color
- Session
- "tabhost requires a tabwidget with id..."问题解决
- UIButton转UIBarButtonItem
- CodeForces 612C Replace To Make Regular Bracket Sequence
- Leetcode #51&52 N-Queens I&II N皇后问题 1&2 解题报告
- Win10系统自带输入法的人机交互设计
- POJ_3061_Subsequence_(尺取法)
- iOS--UINavigationController学习笔记
- 【Android UI】音频条形图
- StringBuffer和StringBuilder的区别