Какие точки использовать для определения оси симметрии по координате x?
Что проверяют
Это задача вида «дано n точек на плоскости, есть ли вертикальная прямая, относительно которой набор симметричен». Проверяют, заметите ли вы, что кандидат на ось один и находится за линейный проход, без перебора пар. Следом спрашивают про дубликаты точек и дробные координаты.
Как отвечать
Ключевое наблюдение: если ось существует, самая левая и самая правая точки обязаны отражаться друг в друга. Значит, ось проходит через x = (min_x + max_x) / 2, и определяют её именно крайние точки, а не произвольные пары с равными y.
Алгоритм:
- границы: один проход, находим
min_xиmax_x; - без деления: храним сумму
s = min_x + max_x. Отражение точки(x, y)это(s - x, y), и при целых координатах можно обойтись без чисел с плавающей точкой; - множество: кладём точки в
setкортежей(x, y), это заодно схлопывает дубликаты; - проверка: для каждой
(x, y)должна найтись(s - x, y). Точки на самой оси отражаются в себя, отдельный случай не нужен.
Итог: O(n) по времени и O(n) по памяти. Вариант без хеширования: сгруппировать точки по y, отсортировать уникальные x в группе и проверить, что суммы крайних пар равны s. Это O(n log n).
Для специальности данных стоит добавить продолжение: на реальных измерениях точного совпадения не будет. Тогда координаты округляют до допуска или ищут отражённую точку ближайшим соседом через scipy.spatial.KDTree с порогом расстояния, а саму ось подбирают, минимизируя суммарное отклонение. Векторно проверку удобно сделать в numpy, идея та же.
Где спотыкаются
Перебирают все пары точек как кандидатов на ось и получают O(n²), хотя две крайние точки задают кандидата однозначно.
Берут за ось среднее x всех точек. С дубликатами это даёт неверный ответ: набор (0, 0), (0, 0), (2, 0) симметричен относительно x = 1, а среднее равно двум третям.
Делят на два и сравнивают float через ==. На координатах вроде 0.1 это ломается, поэтому сравнивают удвоенные значения или работают с допуском.