3102.最小化曼哈顿距离

解题思路

分析时间复杂度,计算任意两点的曼哈顿距离达到 O ( n 2 ) O(n^2) O(n2),会超时需要优化。
因此优化可以将曼哈顿距离与切比雪夫距离的相互关系找出来,然后转换成求切比雪夫距离的方式,得到
d i s t a n c e ( A , B ) = m a x ( ∣ ( x 1 − y 1 ) − ( x 2 − y 2 ) ∣ , ∣ ( x 1 + y 1 ) − ( x 2 + y 2 ) ∣ ) distance(A, B) = max(| (x_1 - y_1) -(x_2 - y_2)|, |(x_1+y_1)-(x_2+y_2)|) distance(A,B)=max((x1y1)(x2y2),(x1+y1)(x2+y2))
。这样,只需要计算每个点的坐标之差、坐标之和即可。
这样,曼达顿距离的最大值,即最大值与最小值的差的最大值。
删除某个点,删除对应的点然后重新计算即可。

曼哈顿距离与切比雪夫距离的相互转换

  • 曼哈顿坐标系是通过切比雪夫坐标系旋45°后,再缩小到原来的一半得到的。
    将一个点 ( x , y ) (x,y) (x,y) 的坐标变为 ( x + y , x − y ) (x + y, x - y) (x+y,xy) 后,原坐标系中的曼哈顿距离等于新坐标系中的切比雪夫距离。
    将一个点 ( x , y ) (x,y) (x,y) 的坐标变为 ( x + y 2 , x − y 2 ) (\frac{x + y}{2},\frac{x - y}{2}) (2x+y,2xy) 后,原坐标系中的切比雪夫距离等于新坐标系中的曼哈顿距离。
    碰到求切比雪夫距离或曼哈顿距离的题目时,我们往往可以相互转化来求解。两种距离在不同的题目中有不同的优缺点,应该灵活运用。

Java

class Solution {
    public int minimumDistance(int[][] points) {
        // 维护距离数组
        // 可以使用映射关系的数据集合进行存储
        TreeMap<Integer, Integer> sx = new TreeMap<Integer, Integer>();
        TreeMap<Integer, Integer> sy = new TreeMap<Integer, Integer>();
        // 遍历二维列表
        for (int[] p : points){
            sx.put(p[0] - p[1], sx.getOrDefault(p[0] - p[1], 0)+1);
            sy.put(p[0] + p[1], sy.getOrDefault(p[0] + p[1], 0)+1);

        }
        int res = Integer.MAX_VALUE;
        for (int[] p : points){
            sx.put(p[0] - p[1], sx.get(p[0] - p[1]) - 1);
            if (sx.get(p[0] - p[1]) == 0){
                sx.remove(p[0] - p[1]);
            }
            sy.put(p[0] + p[1], sy.get(p[0] + p[1]) - 1);
            if (sy.get(p[0] + p[1]) == 0) {
                sy.remove(p[0] + p[1]);
            }
            res = Math.min(res, Math.max(sx.lastKey() - sx.firstKey(), sy.lastKey() - sy.firstKey()));
            sx.put(p[0] - p[1], sx.getOrDefault(p[0] - p[1], 0) + 1);
            sy.put(p[0] + p[1], sy.getOrDefault(p[0] + p[1], 0) + 1);

        }
        return res;
    }
}

C++

class Solution {
public:
    int minimumDistance(vector<vector<int>>& points) {
        // 维护两个集合
        multiset<int> sx, sy;
        for (auto & p : points){
            sx.emplace(p[0] - p[1]);
            sy.emplace(p[0] + p[1]);

        }
        int res = INT_MAX;
        for (auto & p :points){
            // 先消除
            sx.erase(sx.find(p[0] - p[1]));
            sy.erase(sy.find(p[0] + p[1]));
            // 更新
            res = min(res, max(*sx.rbegin() - *sx.begin(), *sy.rbegin() - *sy.begin()));
            sx.emplace(p[0] - p[1]);
            sy.emplace(p[0] + p[1]); // 恢复

        }
        return res;
    }
};

Python

from sortedcontainers import SortedList
class Solution:
    def minimumDistance(self, points: List[List[int]]) -> int:
        sx = SortedList(p[0] - p[1] for p in points)
        sy = SortedList(p[0] + p[1] for p in points)
        res = float('inf')
        for p in points:
            sx.remove(p[0] - p[1])
            sy.remove(p[0] + p[1])
            res = min(res, max(sx[-1] - sx[0], sy[-1] - sy[0]))
            sx.add(p[0] - p[1])
            sy.add(p[0] + p[1])
        return res
  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值