高效求解 n 个点之间的最大曼哈顿距离
2024-07-12 16:18
561
0
平面上有 n 个点,如何求出任意两点的曼哈顿距离的最大值?
曼哈顿距离的公式为:
\[d((x_1, y_1), (x_2, y_2)) = |x_1 - x_2| + |y_1 - y_2|
\]
为了最大化曼哈顿距离,可以考虑绝对值展开的所有情况,我们可以考虑以下四个表达式:
对于点 $ (x_i, y_i) ) 和 ( (x_j, y_j) $,曼哈顿距离 $ |x_i - x_j| + |y_i - y_j| $ 可以转化为以下四种形式之一:
- $ (x_i + y_i) - (x_j + y_j) $
- $ (x_i - y_i) - (x_j - y_j) $
- $ -(x_i + y_i) + (x_j + y_j) $
- $ -(x_i - y_i) + (x_j - y_j) $
那么我们只需要跟踪这两个表达式的最大值和最小值:
- $ f_1(x, y) = x + y $
- $ f_2(x, y) = x - y $
对于每个表达式,我们可以找到其最大值和最小值,然后计算这些最大值和最小值之间的差值。
-
初始化四组变量,用来记录上述四个表达式的最大值和最小值:
- $ \text{max1} = \text{min1} = x_1 + y_1 $
- $ \text{max2} = \text{min2} = x_1 - y_1 $
-
遍历所有点 \((x_i, y_i)\),更新这四个值
-
计算两组差值的最大值:
- $ d1 = \text{max1} - \text{min1} $
- $ d2 = \text{max2} - \text{min2} $
两个值实际上代表了所有四种绝对值展开的情况,几何上即线段从左下到右上和从左上到右下的两种情况。
-
曼哈顿距离的最大值就是最大值:
\[\text{max_distance} = \max(d1, d2) \]
这个算法的时间复杂度为 $ O(n) $,因为只需遍历所有点一次即可完成所有更新和计算。
int maxManhattanDistance(const vector<pair<int, int>>& points) { int max1 = INT_MIN/2, min1 = INT_MAX/2; int max2 = INT_MIN/2, min2 = INT_MAX/2; for (const auto& point : points) { int x = point.first; int y = point.second; // 更新 max1 和 min1 int f1 = x + y; max1 = max(max1, f1); min1 = min(min1, f1); // 更新 max2 和 min2 int f2 = x - y; max2 = max(max2, f2); min2 = min(min2, f2); } int d1 = max1 - min1; int d2 = max2 - min2; return max(d1, d2); } int main() { // 示例输入 vector<pair<int, int>> points = {{1, 2}, {3, 4}, {6, 1}, {-1, -3}}; int maxDistance = maxManhattanDistance(points); cout << "Maximum Manhattan Distance: " << maxDistance << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步