LeetCode-Python-296. 最佳的碰头地点(数学)

有一队人(两人或以上)想要在一个地方碰面,他们希望能够最小化他们的总行走距离。

给你一个 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]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值