Created
December 24, 2015 19:58
-
-
Save guliash/317557420f23ad4afd9a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public ArrayDeque<PairInt> findPoints(PairInt[] points) { | |
ArrayDeque<PairInt> result = new ArrayDeque<>(); | |
int n = points.length; | |
int val, j; | |
int leftBorder, rightBorder; | |
leftBorder = Integer.MAX_VALUE; | |
rightBorder = Integer.MIN_VALUE; | |
Arrays.sort(points, new Comparator<PairInt>() { | |
@Override | |
public int compare(PairInt o1, PairInt o2) { | |
if(o1.y == o2.y) { | |
return o1.x - o2.x; | |
} | |
return o2.y - o1.y; | |
} | |
}); | |
for(int i = 0; i < n;) { | |
val = points[i].y; | |
j = i; | |
for(; j < n && points[j].y == val; j++) {} //ищем следующие максимальные по высоте точки | |
if(points[i].x < leftBorder) { | |
//самая левая из этих точек points[i] | |
result.addFirst(new PairInt(leftBorder, val)); | |
result.addFirst(points[i]); | |
leftBorder = points[i].x; | |
} | |
if(points[j - 1].x > rightBorder) { | |
//самая правая из этих точек points[j - 1] | |
result.addLast(new PairInt(rightBorder, val)); | |
result.addLast(points[j - 1]); | |
rightBorder = points[j - 1].x; | |
} | |
i = j; | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Я предложу несколько иное решение.
Визуально его можно представить следующим образом. Пусть у нас есть пластина какого-то материала. Мы её горизонтально сверху бросаем на нашу фигуру. При встрече с фигурой, она разломится соприкоснувшись с самыми высокими точками следующим образом: найдём самую высокую точку слева и справа, кусок пластины между точками останется лежать на них, а куски по краям полетят дальше вниз. Дальше эти кусочки снова встретятся с другими следующими самыми высокими точками и т.п.. Фигура полученная вот этими кусками и есть искомый забор сверху. Делаем тоже самое для других сторон.
Как это сделать алгоритмически. Рассмотрим случай сверху:
Сортируем точки по убыванию y, а в случае равенства по возрастанию x.
Будем также поддерживать левую и правую границу по x крайних последних разломов.
Далее в цикле слева направо, переходим от уровня к уровню по y, проверяем есть ли разломы за пределами границ и меняем границы.
Можно обобщить этот метод и для нижней стороны.