资讯专栏INFORMATION COLUMN

[LintCode] Build Post Office I & II

1treeS / 1333人阅读

Build Post Office Problem

Given a 2D grid, each cell is either an house 1 or empty 0 (the number zero, one), find the place to build a post office, the distance that post office to all the house sum is smallest. Return the smallest distance. Return -1 if it is not possible.

Notice

You can pass through house and empty.
You only build post office on an empty.

Example

Given a grid:

0 1 0 0
1 0 1 1
0 1 0 0
return 6. (Placing a post office at (1,1), the distance that post office to all the house sum is smallest.)

Solution DP

会超时。

</>复制代码

  1. public class Solution {
  2. public class Node {
  3. int x;
  4. int y;
  5. public Node(int x, int y) {
  6. this.x = x;
  7. this.y = y;
  8. }
  9. }
  10. public int shortestDistance(int[][] grid) {
  11. if (grid == null || grid.length == 0 || grid[0].length == 0) return -1;
  12. ArrayList house = new ArrayList<>();
  13. ArrayList empty = new ArrayList<>();
  14. for (int i = 0; i < grid.length; i++) {
  15. for (int j = 0; j < grid[0].length; j++) {
  16. if (grid[i][j] == 1) {
  17. house.add(new Node(i, j));
  18. }
  19. else {
  20. empty.add(new Node(i, j));
  21. }
  22. }
  23. }
  24. if (empty.size() == 0) return -1;
  25. int min = Integer.MAX_VALUE;
  26. for (Node node: empty) {
  27. min = Math.min(min, helper(house, node));
  28. }
  29. return min;
  30. }
  31. private int helper(ArrayList house, Node node) {
  32. int dist = 0;
  33. for (Node cur: house) {
  34. dist += Math.abs(cur.x - node.x) + Math.abs(cur.y - node.y);
  35. }
  36. return dist;
  37. }
  38. }

</>复制代码

  1. public class Solution {
  2. public int shortestDistance(int[][] grid) {
  3. int m = grid.length, n = grid[0].length;
  4. if (grid == null || m == 0 || n == 0) return -1;
  5. List x = new ArrayList<>();
  6. List y = new ArrayList<>();
  7. List xSum = new ArrayList<>();
  8. List ySum = new ArrayList<>();
  9. int res = Integer.MAX_VALUE;
  10. for (int i = 0; i < m; i++) {
  11. for (int j = 0; j < n; j++) {
  12. if (grid[i][j] == 1) {
  13. x.add(i);
  14. y.add(j);
  15. }
  16. }
  17. }
  18. Collections.sort(x);
  19. Collections.sort(y);
  20. int total = x.size();
  21. xSum.add(0);
  22. ySum.add(0);
  23. for (int i = 1; i <= total; i++) {
  24. xSum.add(xSum.get(i-1) + x.get(i-1));
  25. ySum.add(ySum.get(i-1) + y.get(i-1));
  26. }
  27. for (int i = 0; i < m; i++) {
  28. for (int j = 0; j < n; j++) {
  29. if (grid[i][j] == 0) {
  30. int costX = getCost(x, xSum, i, total);
  31. int costY = getCost(y, ySum, j, total);
  32. if (costX + costY < res) res = costX + costY;
  33. }
  34. }
  35. }
  36. return res;
  37. }
  38. public int getCost(List list, List sum, int pos, int size) {
  39. if (size == 0) return 0;
  40. if (list.get(0) > pos) return sum.get(size) - pos * size;
  41. int l = 0, r = size-1;
  42. while (l + 1 < r) {
  43. int mid = l + (r-l)/2;
  44. if (list.get(mid) <= pos) l = mid;
  45. else r = mid-1;
  46. }
  47. int index = 0;
  48. if (list.get(r) <= pos) index = r;
  49. else index = l;
  50. return sum.get(size) - sum.get(index+1) - pos * (size-index-1) + pos * (index+1) - sum.get(index+1);
  51. }
  52. }
Build Post Office II Problem

Given a 2D grid, each cell is either a wall 2, an house 1 or empty 0 (the number zero, one, two), find the place to build a post office, the distance that post office to all the house sum is smallest. Return the smallest distance. Return -1 if it is not possible.

Notice

You cannot pass through wall and house, but can pass through empty.
You only build post office on an empty.

Example

Given a grid:

</>复制代码

  1. 0 1 0 0 0
  2. 1 0 0 2 1
  3. 0 1 0 0 0

return 8, You can build at (1,1). (Placing a post office at (1,1), the distance that post office to all the house sum is smallest.)

Challenge

Solve this problem within O(n^3) time.

Solution

</>复制代码

  1. public class Solution {
  2. class Node {
  3. int x, y, dist;
  4. public Node(int x, int y, int dist) {
  5. this.x = x;
  6. this.y = y;
  7. this.dist = dist;
  8. }
  9. }
  10. public int shortestDistance(int[][] grid) {
  11. if (grid == null || grid.length == 0 || grid[0].length == 0) return -1;
  12. int m = grid.length;
  13. int n = grid[0].length;
  14. List house = new ArrayList<>();
  15. List empty = new ArrayList<>();
  16. for (int i = 0; i < m; i++) {
  17. for (int j = 0; j < n; j++) {
  18. if (grid[i][j] == 1) house.add(new Node(i, j, 0));
  19. else if (grid[i][j] == 0) empty.add(new Node(i, j, 0));
  20. }
  21. }
  22. if (empty.size() == 0) return -1;
  23. int k = house.size();
  24. int[][][] distance = new int[k][m][n];
  25. for (int i = 0; i < k; i++) {
  26. for (int j = 0; j < m; j++) {
  27. Arrays.fill(distance[i][j], Integer.MAX_VALUE);
  28. }
  29. }
  30. boolean[][] visited;
  31. for (int i = 0; i < k; i++) {
  32. visited = new boolean[m][n];
  33. getDistance(house.get(i), distance, i, grid, visited);
  34. }
  35. int min = Integer.MAX_VALUE;
  36. for (int i = 0; i < m; i++) {
  37. for (int j = 0; j < n; j++) {
  38. if (grid[i][j] == 0) {
  39. int sum = 0;
  40. for (int l = 0; l < k; l++) {
  41. if (distance[l][i][j] == Integer.MAX_VALUE) {
  42. sum = Integer.MAX_VALUE;
  43. break;
  44. }
  45. sum += distance[l][i][j];
  46. }
  47. min = Math.min(min, sum);
  48. }
  49. }
  50. }
  51. if (min == Integer.MAX_VALUE) return -1;
  52. return min;
  53. }
  54. int[] dx = {-1, 1, 0, 0};
  55. int[] dy = {0, 0, -1, 1};
  56. private void getDistance(Node cur, int[][][] distance, int k, int[][] grid, boolean[][] visited) {
  57. Queue q = new LinkedList();
  58. q.offer(cur);
  59. visited[cur.x][cur.y] = true;
  60. int m = grid.length;
  61. int n = grid[0].length;
  62. while (!q.isEmpty()) {
  63. Node now = q.poll();
  64. for (int i = 0; i < 4; i++) {
  65. int nextX = now.x + dx[i];
  66. int nextY = now.y + dy[i];
  67. if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n && grid[nextX][nextY] == 0 && !visited[nextX][nextY]) {
  68. distance[k][nextX][nextY] = now.dist + 1;
  69. q.add(new Node(nextX, nextY, now.dist+1));
  70. visited[nextX][nextY] = true;
  71. }
  72. }
  73. }
  74. }
  75. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66054.html

相关文章

  • [LintCode] Segment Tree Query I &amp; Segment Tree

    摘要:题目是要查询到这个区间内某一点的。值是从最底层的子节点值里取最大值。因此,不用太复杂,递归就可以了。与所不同的是,对所给区间内的元素个数求和,而非筛选。这样就会出现的情况,视作本身处理。 Segment Tree Query Problem For an integer array (index from 0 to n-1, where n is the size of this ar...

    vibiu 评论0 收藏0
  • [LintCode] Segment Tree Build &amp; Segment Tree B

    摘要:唯一需要注意的就是的赋值取左右子树的的较大值,最后一层的独立结点的为对应数组中的值。 Segment Tree Build I Problem The structure of Segment Tree is a binary tree which each node has two attributes start and end denote an segment / interv...

    honhon 评论0 收藏0
  • [LintCode/LeetCode] Subsets &amp; Subsets II

    Subsets Problem Given a set of distinct integers, return all possible subsets. Notice Elements in a subset must be in non-descending order.The solution set must not contain duplicate subsets. Example ...

    tracy 评论0 收藏0
  • [LintCode/LeetCode] Single Number I &amp; II [位运算]

    摘要:整个过程相当于,直接在和里去掉既是又是的。所以最后返回的,一定是只出现过一次的,而出现两次的都在里,出现三次的都被消去了。 Single Number I Problem Given 2*n + 1 numbers, every numbers occurs twice except one, find it. Example Given [1,2,2,1,3,4,3], return...

    Drinkey 评论0 收藏0
  • [LintCode] Spiral Matrix I &amp; Spiral Matrix II

    摘要:如果不在前两个循环之后的话,那么那多余的一行或一列就会被加入数组两次,造成错误的结果。解法和一样,只是简化了,甚至可以用一样的方法去做,只要把也换成。使用,以及最后讨论是否为奇数以判断中间是否有一个未循环的点,是这道题的两个有趣的地方。 Spiral Matrix I Problem Given a matrix of m x n elements (m rows, n columns...

    tuantuan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<