SWE · Coding

点集最大矩形:等长同中点的对角线分组

矩形不必平行坐标轴,用整数几何避免浮点相等。

题目重点:矩形不必平行坐标轴,用整数几何避免浮点相等。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 整数坐标,重复坐标归一化;选四个不同点组成非退化矩形,返回最大面积,不存在为0。
  • 本文讨论任意方向矩形;只允许轴对齐的版本在追问中单独说明。

解题路线

  1. 矩形的两对角线有同一中点且长度相等;反过来两个不同点对有此属性,构成等对角线平行四边形,即矩形。
  2. 对每点对(a,c)计算key=(ax+cx,ay+cy,平方距离),不除2、不求平方根。每个key内枚举两条不同对角线,选四端点。
  3. 面积用相邻边向量叉积绝对值,例如从a到另一对角线两端b/d。不要把两对角线叉积直接当面积,它等于面积两倍。

手动走一遍

点(0,1),(1,0),(2,1),(1,2)组成旋转正方形,两对角线和坐标均(2,2)、平方长4,面积2。轴对齐(0,0),(3,0),(3,2),(0,2)也被覆盖,面积6;只有三点则0。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from collections import defaultdict
from itertools import combinations


def largest_rectangle(points):
    points = list(dict.fromkeys(map(tuple,points)))
    groups = defaultdict(list)
    for a,c in combinations(points,2):
        key = (a[0]+c[0],a[1]+c[1],(a[0]-c[0])**2+(a[1]-c[1])**2)
        groups[key].append((a,c))
    answer = 0
    for diagonals in groups.values():
        for (a,c),(b,d) in combinations(diagonals,2):
            if len({a,b,c,d}) != 4:
                continue
            area = abs((b[0]-a[0])*(d[1]-a[1])-(b[1]-a[1])*(d[0]-a[0]))
            answer = max(answer,area)
    return answer

复杂度

n唯一点,建组O(n²)期望时间/空间;组内枚举Σk²,保守O(n⁴),可利用同key每点仅一个对点推出k≤n/2,整体O(n³)上界。实际取决于圆上点的分布。

易错点与追问

容易失分的边界

  • 矩形对角线中点同但长度不同只是平行四边形。
  • 浮点坐标要另定近似几何与误差标准,不能直接用epsilon做哈希等价类。

继续深挖

  • 只允许轴对齐时,怎样按横坐标与共同纵坐标对减少工作?
  • 返回顶点顺序怎样保证没有自交,且并列最大如何规定?
✓已复制微信号!