您的位置:首页 > 产品设计 > UI/UE

[LeetCode] Shortest Distance from All Buildings

2015-12-15 15:10 429 查看
之前听朋友说LeetCode出了一道新题,但是一直在TLE,我就找时间做了一下。这题是一个比较典型的BFS的题目,自己匆忙写了一个答案,没有考虑优化的问题,应该是有更好的解法的。

基本想法就是从每个数值为1的点做bfs,遇到为0的点就加上相应的距离。这题因为要求到所有1的距离和最小的点,所以就可以无脑iterate over所有数值为1的点,并开一个二维数组来记录各个点的累加距离值。最后要检查一下所有结果中的值,确保其可以reach到所有的值为1的点,若不存在这样的,则返回-1。代码如下,比较冗长,等有机会再优化一下吧。

public class Solution {
public int shortestDistance(int[][] grid) {
int result = Integer.MAX_VALUE;
boolean[][] done = new boolean[grid.length][grid[0].length];
int[][] cost = new int[grid.length][grid[0].length];
int[][] count = new int[grid.length][grid[0].length];
int total = 0; // total # of 1
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
done[i][j] = grid[i][j] != 0;
total = grid[i][j] == 1 ? total + 1 : total;
}
}
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
Deque<Integer> row = new ArrayDeque<>();
Deque<Integer> col = new ArrayDeque<>();
enqueue(row, col, i, j, done, grid);
bfs(row, col, grid, cost, done, count, 1);
}
}
}
if (!isValid(count, total)) {
return -1;
}
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost[0].length; j++) {
if (count[i][j] == total) {
result = cost[i][j] > 0 ? Math.min(result, cost[i][j]) : result;
}
}
}
return result;
}

private void bfs(Deque<Integer> row, Deque<Integer> col, int[][] grid, int[][] cost, boolean[][] done, int[][] count, int distance) {
if (row.isEmpty()) {
return;
}
int size = row.size();
List<Integer> row1 = new ArrayList<>();
List<Integer> col1 = new ArrayList<>();
for (int k = 0; k < size; k++) {
int i = row.poll();
int j = col.poll();
row1.add(i);
col1.add(j);
cost[i][j] += distance;
count[i][j] += 1;
enqueue(row, col, i, j, done, grid);
}
bfs(row, col, grid, cost, done, count, distance + 1);
for (int i = 0; i < row1.size(); i++) {
done[row1.get(i)][col1.get(i)] = false;
}
}

private void enqueue(Deque<Integer> row, Deque<Integer> col, int i, int j, boolean[][] done, int[][] grid) {
int down = i + 1;
int up = i - 1;
int left = j - 1;
int right = j + 1;
if (up >= 0 && !done[up][j] && grid[up][j] == 0) {
row.offer(up);
col.offer(j);
done[up][j] = true;
}
if (down < grid.length && !done[down][j] && grid[down][j] == 0) {
row.offer(down);
col.offer(j);
done[down][j] = true;
}
if (left >= 0 && !done[i][left] && grid[i][left] == 0) {
row.offer(i);
col.offer(left);
done[i][left] = true;
}
if (right < grid[0].length && !done[i][right] && grid[i][right] == 0) {
row.offer(i);
col.offer(right);
done[i][right] = true;
}
}

private boolean isValid(int[][] count, int total) {
for (int[] aCount : count) {
for (int c : aCount) {
if (c == total) {
return true;
}
}
}
return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: