package divideconquer;import java.util.ArrayList;import java.util.Comparator;/*** @author dimgrichr* <p>Space complexity: O(n) Time complexity: O(nlogn), because it is a divide and conquer* algorithm*/public class SkylineAlgorithm {private ArrayList<Point> points;/*** Main constructor of the application. ArrayList points gets created, which represents the sum of* all edges.*/public SkylineAlgorithm() {points = new ArrayList<>();}/** @return points, the ArrayList that includes all points. */public ArrayList<Point> getPoints() {return points;}/*** The main divide and conquer, and also recursive algorithm. It gets an ArrayList full of points* as an argument. If the size of that ArrayList is 1 or 2, the ArrayList is returned as it is, or* with one less point (if the initial size is 2 and one of it's points, is dominated by the other* one). On the other hand, if the ArrayList's size is bigger than 2, the function is called* again, twice, with arguments the corresponding half of the initial ArrayList each time. Once* the flashback has ended, the function produceFinalSkyLine gets called, in order to produce the* final skyline, and return it.** @param list, the initial list of points* @return leftSkyLine, the combination of first half's and second half's skyline* @see Point*/public ArrayList<Point> produceSubSkyLines(ArrayList<Point> list) {// part where function exits flashbackint size = list.size();if (size == 1) {return list;} else if (size == 2) {if (list.get(0).dominates(list.get(1))) {list.remove(1);} else {if (list.get(1).dominates(list.get(0))) {list.remove(0);}}return list;}// recursive part of the functionArrayList<Point> leftHalf = new ArrayList<>();ArrayList<Point> rightHalf = new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (i < list.size() / 2) {leftHalf.add(list.get(i));} else {rightHalf.add(list.get(i));}}ArrayList<Point> leftSubSkyLine = produceSubSkyLines(leftHalf);ArrayList<Point> rightSubSkyLine = produceSubSkyLines(rightHalf);// skyline is producedreturn produceFinalSkyLine(leftSubSkyLine, rightSubSkyLine);}/*** The first half's skyline gets cleared from some points that are not part of the final skyline* (Points with same x-value and different y=values. The point with the smallest y-value is kept).* Then, the minimum y-value of the points of first half's skyline is found. That helps us to* clear the second half's skyline, because, the points of second half's skyline that have greater* y-value of the minimum y-value that we found before, are dominated, so they are not part of the* final skyline. Finally, the "cleaned" first half's and second half's skylines, are combined,* producing the final skyline, which is returned.** @param left the skyline of the left part of points* @param right the skyline of the right part of points* @return left the final skyline*/public ArrayList<Point> produceFinalSkyLine(ArrayList<Point> left, ArrayList<Point> right) {// dominated points of ArrayList left are removedfor (int i = 0; i < left.size() - 1; i++) {if (left.get(i).x == left.get(i + 1).x && left.get(i).y > left.get(i + 1).y) {left.remove(i);i--;}}// minimum y-value is foundint min = left.get(0).y;for (int i = 1; i < left.size(); i++) {if (min > left.get(i).y) {min = left.get(i).y;if (min == 1) {i = left.size();}}}// dominated points of ArrayList right are removedfor (int i = 0; i < right.size(); i++) {if (right.get(i).y >= min) {right.remove(i);i--;}}// final skyline found and returnedleft.addAll(right);return left;}public static class Point {private int x;private int y;/*** The main constructor of Point Class, used to represent the 2 Dimension points.** @param x the point's x-value.* @param y the point's y-value.*/public Point(int x, int y) {this.x = x;this.y = y;}/** @return x, the x-value */public int getX() {return x;}/** @return y, the y-value */public int getY() {return y;}/*** Based on the skyline theory, it checks if the point that calls the function dominates the* argument point.** @param p1 the point that is compared* @return true if the point wich calls the function dominates p1 false otherwise.*/public boolean dominates(Point p1) {// checks if p1 is dominatedreturn (this.x < p1.x && this.y <= p1.y) || (this.x <= p1.x && this.y < p1.y);}}/*** It is used to compare the 2 Dimension points, based on their x-values, in order get sorted* later.*/class XComparator implements Comparator<Point> {@Overridepublic int compare(Point a, Point b) {return Integer.compare(a.x, b.x);}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。