题目地址:
https://www.lintcode.com/problem/best-meeting-point/description
给定一个二维 0 − 1 0-1 0−1矩阵,要求返回一个坐标,使得所有 1 1 1和这个坐标的曼哈顿距离和最小。返回那个曼哈顿距离。
由于曼哈顿距离是两个坐标差的绝对值之和,所以如果我们能分别最小化两个坐标上的距离,就一定能得到总体的最小曼哈顿距离。这是个几何问题。设数轴上有若干点 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn,不妨设 x 1 ≤ x 2 ≤ . . . ≤ x n x_1\le x_2\le ...\le x_n x1≤x2≤...≤xn,寻找 y y y使得 s ( y ) = ∑ i = 1 n ∣ x i − y ∣ s(y)=\sum_{i=1}^{n}|x_i-y| s(y)=∑i=1n∣xi−y∣最小。显然 y ∈ [ x 1 , x n ] y\in [x_1,x_n] y∈[x1,xn],否则如果 y < x 1 y<x_1 y<x1时有 s ( y ) > s ( x 1 ) s(y)>s(x_1) s(y)>s(x1),如果 y > x n y>x_n y>xn时有 s ( y ) > s ( x n ) s(y)>s(x_n) s(y)>s(xn)。我们只需考虑导数 s ′ ( y ) s'(y) s′(y)即可。如果 x 1 ≤ . . . ≤ x i ≤ y ≤ x i + 1 ≤ . . . ≤ x n x_1\le ...\le x_i\le y\le x_{i+1}\le ...\le x_n x1≤...≤xi≤y≤xi+1≤...≤xn,则 s ′ ( y ) = i − ( n − i ) = 2 i − n s'(y)=i-(n-i)=2i-n s′(y)=i−(n−i)=2i−n,所以在 i = n / 2 i=n/2 i=n/2时 s ( y ) s(y) s(y)取最小值,也就是说要取 y y y为中位数即可(要根据 n n n奇偶性分别讨论。这里就省略了)。代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution {
/**
* @param grid: a 2D grid
* @return: the minimize travel distance
*/
public int minTotalDistance(int[][] grid) {
// Write your code here
if (grid == null || grid.length == 0) {
return 0;
}
List<Integer> row = new ArrayList<>(), col = new ArrayList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
row.add(i);
col.add(j);
}
}
}
Collections.sort(row);
Collections.sort(col);
// 取所有横坐标和纵坐标的中位数即可
int x = row.get(row.size() / 2), y = col.get(col.size() / 2);
int res = 0;
for (int r : row) {
res += Math.abs(r - x);
}
for (int c : col) {
res += Math.abs(c - y);
}
return res;
}
}
时间复杂度 O ( r c + n log n ) O(rc+n\log n) O(rc+nlogn)( r r r和 c c c为矩阵的长宽, n n n为 1 1 1的个数),空间 O ( n ) O(n) O(n)。