Как учесть дублированные точки при проверке симметрии?
Что проверяют
Умеете ли вы уточнить условие до того, как писать код. Слово «дубликаты» тут ключевое: считать ли набор множеством, где повтор ничего не меняет, или мультимножеством, где у каждой копии должна быть своя пара. Следом обычно спрашивают про точки на самой оси и про сложность.
Как отвечать
Сначала задайте два вопроса. Какая симметрия: относительно вертикальной прямой (классическая задача Line Reflection) или относительно точки. И как трактовать повторы. Дальше решение для вертикальной оси, для центральной симметрии идея та же.
Ось, если она существует, проходит ровно посередине между крайними точками: x = (min_x + max_x) / 2. Чтобы не связываться с дробями, храните сумму s = min_x + max_x: отражение точки (x, y) это (s-x, y).
- семантика множества:
pts = set(map(tuple, points)), затемall((s-x, y) in pts for x, y in pts). Дубликаты схлопываются сами, и это верно, если по условию важны только позиции; - семантика мультимножества:
cnt = Counter(map(tuple, points)), и для каждой точки нужноcnt[(x, y)] == cnt[(s-x, y)]. Точка на оси (2 * x == s) отражается сама в себя, поэтому её количество может быть любым; - сложность: O(n) по времени и памяти против O(n²) у попарного перебора. Через сортировку тоже можно, за O(n log n).
Обязательно проговорите граничные случаи: пустой список (обычно True), одна точка, все точки на одной вертикали. И прогоните решение вслух на примере [(1, 1), (1, 1), (-1, 1)]: как множество он симметричен относительно x = 0, как мультимножество нет.
Где спотыкаются
Сразу делают set(points) и не проговаривают, что тем самым выбрали трактовку задачи. Интервьюер может ждать именно подсчёта копий, и тогда решение неверно, хотя простые тесты проходит.
Считают ось делением и сравнивают вещественные числа напрямую. На дробных координатах погрешность в последнем знаке не даёт точке найти своё отражение в множестве. На целых сумма min_x + max_x убирает деление совсем, для вещественных нужен допуск или округление.
Забывают, что точки часто приходят списками: [1, 2] нельзя положить в set, потому что список нехэшируемый. Отсюда map(tuple, points) перед всем остальным.