订阅更新

平面上两点最近距离:笛卡尔积要减半

SQL 实战 123 题 · 第 38 题 中等 约 2 分钟读完

LeetCode 612 · 自连接、笛卡尔积、减少重复计算

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

点两两比较需要自连接,我会加方向条件让每对只算一次,比如 (p1.x, p1.y) < (p2.x, p2.y) 的字典序比较,再对距离平方取 MIN,最后开方并保留两位。点很多时笛卡尔积是 O(n²),真实场景要先按网格分桶再比较。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

点表保存了平面上若干个互不重合的点的坐标。求任意两点之间的最短距离,保留两位小数。

表结构

  • point_2d:x、y;(x, y) 为主键

思路

两两比较只能自连接。第一种写法连接条件是「两点不同」,每对点会算两次(A-B 和 B-A)。第二种写法给连接加了方向约束,让每对点只算一次。另外开方是单调的,可以先对距离平方取最小值,最后只开一次方。

参考解法

写法 1:所有不同点两两配对

SELECT
    ROUND(SQRT(MIN((POW(p1.x - p2.x, 2) + POW(p1.y - p2.y, 2)))), 2) AS shortest
FROM
    point_2d p1
        JOIN
    point_2d p2 ON p1.x != p2.x OR p1.y != p2.y

写法 2:加方向约束,每对点只比较一次

SELECT
    ROUND(SQRT(MIN((POW(p1.x - p2.x, 2) + POW(p1.y - p2.y, 2)))),2) AS shortest
FROM
    point_2d p1
        JOIN
    point_2d p2 ON (p1.x <= p2.x AND p1.y < p2.y)
        OR (p1.x <= p2.x AND p1.y > p2.y)
        OR (p1.x < p2.x AND p1.y = p2.y)

易错点

  • 连接条件写成 p1.x != p2.x AND p1.y != p2.y 会漏掉 x 或 y 相同的点对。
  • SQRT 放在 MIN 外面只算一次;放在里面每对都要开方。
刷题进度保存在当前浏览器