这道题的核心思路与 Java 版本一致,需要通过坐标变换将曼哈顿距离转化为切比雪夫距离,然后利用有序容器动态维护最值。
主要步骤:
1. 坐标变换:将点 (x, y) 转换为 (x+y, x-y)
2. 关键性质:原曼哈顿距离 = 变换后切比雪夫距离 = max(|Δu|, |Δv|)
3. 全局最大距离 = max( (u_max - u_min), (v_max - v_min) )
4. 枚举删除:使用 multiset 维护所有点的 u 和 v,每次删除一个点,计算当前最大距离,取最小值
```cpp
#include <vector>
#include <set>
#include <algorithm>
#include <climits>
using namespace std;
class Solution {
public:
int minimumDistance(vector<vector<int>>& points) {
multiset<int> sums; // 存储所有 x+y
multiset<int> diffs; // 存储所有 x-y
// 初始化所有点的变换坐标
for (const auto& p : points) {
sums.insert(p[0] + p[1]);
diffs.insert(p[0] - p[1]);
}
int ans = INT_MAX;
// 尝试移除每一个点
for (const auto& p : points) {
int sum = p[0] + p[1];
int diff = p[0] - p[1];
// 移除当前点
sums.erase(sums.find(sum));
diffs.erase(diffs.find(diff));
// 计算剩余点的最大曼哈顿距离
int currentMax = max(
*sums.rbegin() - *sums.begin(), // u 的范围
*diffs.rbegin() - *diffs.begin() // v 的范围
);
ans = min(ans, currentMax);
// 恢复当前点,用于下一轮枚举
sums.insert(sum);
diffs.insert(diff);
}
return ans;
}
};
```
复杂度分析:
· 时间复杂度:O(n log n),其中 n 是点的数量。遍历每个点 O(n),每次插入删除 O(log n)
· 空间复杂度:O(n),用于存储两个 multiset
注意:
· 使用 multiset 而非 set,因为可能存在重复坐标
· 删除时要使用 find() 获取迭代器,避免删除所有相同值的元素
· 使用 rbegin() 获取最大值,begin() 获取最小值