Как оптимизировать поиск минимального и максимального расстояния
Что проверяют
Уточните ли вы постановку. «Минимальное и максимальное расстояние» может означать расстояния от одной точки до множества, а может означать ближайшую и самую далёкую пару среди всех точек, и это задачи разной сложности. Следом просят оценить сложность и спрашивают, что изменится при большом числе запросов или для координат на карте.
Как отвечать
Разберите оба варианта:
- от одной точки до n точек: хватает одного прохода за O(n), минимум и максимум обновляются в том же цикле. Сравнивайте квадраты расстояний: корень монотонен и порядок не меняет, поэтому
sqrtнужен один раз, для ответа. В Swift удобно взятьSIMD2<Double>иsimd_distance_squared, а однопроходныйminAndMax()есть в пакете Swift Algorithms; - много запросов к одному множеству: пространственный индекс, k-d дерево, сетка или квадродерево. Построение окупается, и поиск ближайшего перестаёт быть линейным;
- ближайшая пара среди всех: перебор стоит O(n²), «разделяй и властвуй» или сканирующая прямая дают O(n log n);
- самая далёкая пара: она всегда лежит на выпуклой оболочке. Оболочка строится за O(n log n), например монотонной цепочкой Эндрю, а обходится вращающимися калиперами за линейное время.
Для iOS добавьте географию. Если точки это широта и долгота, евклидова формула по градусам врёт: градус долготы укорачивается к полюсам. Берите CLLocation.distance(from:), он возвращает расстояние по поверхности Земли в метрах, или переводите точки в MKMapPoint и считайте на плоской проекции. Тяжёлый расчёт на тысячах точек уводите с главного потока.
Где спотыкаются
Сразу пишут код для расстояния до начала координат, не спросив, о чём задача. Если имелись в виду пары, решение не засчитают.
Сортируют массив ради минимума и максимума. Это O(n log n) и лишняя память там, где хватает одного прохода.
Считают расстояния по градусам как на плоскости или гоняют CLLocation в горячем цикле по десяткам тысяч точек, не отбросив дальних кандидатов грубым фильтром по прямоугольнику.