Question
A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using , where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|
.
For example, given three people living at (0,0)
, (0,4)
, and (2,2)
:
1 - 0 - 0 - 0 - 1| | | | |0 - 0 - 0 - 0 - 0| | | | |0 - 0 - 1 - 0 - 0
The point (0,2)
is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6.
Hint:
- Try to solve it in one dimension first. How can this solution apply to the two dimension case?
Solution 1 -- Sort
根据曼哈顿距离的表达式,我们可以把这个问题转化为求每一维的最短距离。
总距离 = x上最短总距离 + y上最短总距离
并且,我们观察到,对于一个序列,如 [0,0,1,0,1,0,1,1,1,0,0,1]
当邮局选在median的位置时,距离和是最小的。
因此,这里我们遍历数组,得到home的x和y坐标值,然后分别对这两个list排序。再用双指针得到总的最短距离和。
Time complexity O(mn log(mn))
1 public class Solution { 2 public int minTotalDistance(int[][] grid) { 3 if (grid == null || grid.length < 1) { 4 return 0; 5 } 6 int m = grid.length, n = grid[0].length; 7 ListxList = new ArrayList (); 8 List yList = new ArrayList (); 9 for (int i = 0; i < m; i++) {10 for (int j = 0; j < n; j++) {11 if (grid[i][j] == 1) {12 xList.add(i);13 yList.add(j);14 }15 }16 }17 return calcTotalDistance(xList) + calcTotalDistance(yList);18 }19 20 private int calcTotalDistance(List list) {21 if (list == null || list.size() < 2) {22 return 0;23 }24 Collections.sort(list);25 int len = list.size();26 int i = 0, j = len - 1;27 int result = 0;28 while (i < j) {29 int left = list.get(i);30 int right = list.get(j);31 result += (right - left);32 i++;33 j--;34 }35 return result;36 }37 }
Solution 2 -- Without sorting
Discussion里有人给出了不用排序的方法。时间复杂度降低为O(mn)
因为双层循环遍历数组本身就是有次序性的。
1. 外层循环为遍历行,内层循环为遍历该行的每一个元素。
这样得到的是排序好的x的list
2. 外层循环为遍历列,内层循环为遍历该列的每一个元素。
这样得到的是排序好的y的list
1 public class Solution { 2 public int minTotalDistance(int[][] grid) { 3 if (grid == null || grid.length < 1) { 4 return 0; 5 } 6 int m = grid.length, n = grid[0].length; 7 ListxList = new ArrayList (); 8 List yList = new ArrayList (); 9 for (int i = 0; i < m; i++) {10 for (int j = 0; j < n; j++) {11 if (grid[i][j] == 1) {12 xList.add(i);13 }14 }15 }16 for (int j = 0; j < n; j++) {17 for (int i = 0; i < m; i++) {18 if (grid[i][j] == 1) {19 yList.add(j);20 }21 }22 }23 24 return calcTotalDistance(xList) + calcTotalDistance(yList);25 }26 27 private int calcTotalDistance(List list) {28 if (list == null || list.size() < 2) {29 return 0;30 }31 int len = list.size();32 int i = 0, j = len - 1;33 int result = 0;34 while (i < j) {35 result += (list.get(j--) - list.get(i++));36 }37 return result;38 }39 }