The "Best Meeting Point" problem asks you to find a location on a 2D grid where a group of people can meet so that the sum of their travel distances is minimized. The grid is represented as a 2D list of integers, where a cell with value 1
means a person is located there and 0
means the cell is empty.
Your task is to return the minimum total Manhattan distance (the sum of absolute differences of their coordinates) for all people to meet at a single grid cell. Any cell can be chosen as the meeting point, and multiple people can start from the same row or column.
At first glance, it might seem natural to try all possible meeting points and calculate the sum of distances for each. However, this brute-force approach would be very slow for larger grids, as it would require checking every cell for every person.
To optimize, we need to realize that the Manhattan distance is the sum of the absolute differences along each axis (row and column). This means we can separate the problem into two 1D problems: one for rows and one for columns. For each dimension, the optimal meeting point is at the median of the people's coordinates. This is because the median minimizes the sum of absolute differences.
So, the key insight is that we should:
Let's break down the optimized solution step by step:
1
, record its row and column indices.This approach is efficient because sorting and median-finding are much faster than checking every possible meeting point.
Let's consider the following grid:
1 0 0 0 1 0 0 0 0 0 0 0 1 0 0
Step-by-step:
So, the minimum total distance is 6, with the best meeting point at (0,2).
m
rows, n
columns, and k
people, the complexity is O(m * n * k).
The Best Meeting Point problem leverages the property that the sum of Manhattan distances is minimized at the median. By separating the rows and columns and focusing on their medians, we avoid brute-force searching and achieve an efficient solution. This approach is elegant and powerful, transforming a complex 2D problem into two simple 1D problems.
class Solution:
def minTotalDistance(self, grid):
rows = []
cols = []
m, n = len(grid), len(grid[0])
# Collect row indices
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
rows.append(i)
# Collect column indices
for j in range(n):
for i in range(m):
if grid[i][j] == 1:
cols.append(j)
# Find median
def minDist(points):
points.sort()
median = points[len(points)//2]
return sum(abs(p - median) for p in points)
return minDist(rows) + minDist(cols)
class Solution {
public:
int minTotalDistance(vector<vector<int>>& grid) {
vector<int> rows, cols;
int m = grid.size(), n = grid[0].size();
// Collect row indices
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j] == 1) rows.push_back(i);
// Collect column indices
for (int j = 0; j < n; ++j)
for (int i = 0; i < m; ++i)
if (grid[i][j] == 1) cols.push_back(j);
// Find median and sum distances
auto minDist = [](vector<int>& points) {
sort(points.begin(), points.end());
int median = points[points.size() / 2];
int total = 0;
for (int p : points)
total += abs(p - median);
return total;
};
return minDist(rows) + minDist(cols);
}
};
class Solution {
public int minTotalDistance(int[][] grid) {
List<Integer> rows = new ArrayList<>();
List<Integer> cols = new ArrayList<>();
int m = grid.length, n = grid[0].length;
// Collect row indices
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j] == 1) rows.add(i);
// Collect column indices
for (int j = 0; j < n; ++j)
for (int i = 0; i < m; ++i)
if (grid[i][j] == 1) cols.add(j);
// Find median and sum distances
int total = minDist(rows) + minDist(cols);
return total;
}
private int minDist(List<Integer> points) {
Collections.sort(points);
int median = points.get(points.size() / 2);
int sum = 0;
for (int p : points)
sum += Math.abs(p - median);
return sum;
}
}
var minTotalDistance = function(grid) {
let rows = [], cols = [];
let m = grid.length, n = grid[0].length;
// Collect row indices
for (let i = 0; i < m; ++i)
for (let j = 0; j < n; ++j)
if (grid[i][j] === 1) rows.push(i);
// Collect column indices
for (let j = 0; j < n; ++j)
for (let i = 0; i < m; ++i)
if (grid[i][j] === 1) cols.push(j);
// Find median and sum distances
function minDist(points) {
points.sort((a, b) => a - b);
let median = points[Math.floor(points.length / 2)];
return points.reduce((sum, p) => sum + Math.abs(p - median), 0);
}
return minDist(rows) + minDist(cols);
};