有一队人(两人或以上)想要在一个地方碰面,他们希望能够最小化他们的总行走距离。
给你一个 2D 网格,其中各个格子内的值要么是 0,要么是 1。
1 表示某个人的家所处的位置。这里,我们将使用 曼哈顿距离 来计算,其中 distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|。
示例:
输入:
1 - 0 - 0 - 0 - 1
| | | | |
0 - 0 - 0 - 0 - 0
| | | | |
0 - 0 - 1 - 0 - 0
输出: 6
解析: 给定的三个人分别住在(0,0),(0,4) 和 (2,2):
(0,2) 是一个最佳的碰面点,其总行走距离为 2 + 2 + 2 = 6,最小,因此返回 6。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-meeting-point
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
先考虑一维的情况,如果所有人都住在一条直线上,想要找到使总行走距离最小的一个见面点,
这个见面点应当设置为所有人居住位置的中位数。
推广到二维,其实就是横向找一个中位数,再纵向找一个中位数,即可得到最佳见面点,
然后计算每个人到见面点的距离即可。
时间复杂度:O(MN + MlogM + NlogN),其实可以优化,根据遍历的方式,有一个方向上无需排序
空间复杂度:O(K), K是总人数,最多等于MN
class Solution(object):
def minTotalDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if not grid or not grid[0]:
return -1
m, n = len(grid), len(grid[0])
row, col = [], []
for i in range(m):
for j in range(n):
if grid[i][j]:
row.append(i)
col.append(j)
meet_point = [self.findMedian(row), self.findMedian(col)]
res = 0
for i in range(m):
for j in range(n):
if grid[i][j]:
res += abs(i - meet_point[0]) + abs(j - meet_point[1])
return res
def findMedian(self, nums):
nums.sort()
return nums[len(nums) // 2]