I'm working on a project where I have to find the skyline of the points that are not dominated by any other point in the set. A point A(x1,y1) dominates point B(x2,y2) if x1<=x2 && y1<=y2. Here's an example
This is my code:
public static ArrayList<Point> findSkyline(ArrayList<Point> pointsList){
if (pointsList.size()<=1){
return pointsList;
}
ArrayList<Point> leftSkylinePoints=new ArrayList<>();
ArrayList<Point> rightSkylinePoints=new ArrayList<>();
ArrayList<Point> leftPoints=new ArrayList<>();
ArrayList<Point> rightPoints=new ArrayList<>();
for (int i=0;i<pointsList.size()/2;i++){
leftPoints.add(pointsList.get(i));
}
for (int i=pointsList.size()/2;i<pointsList.size();i++){
rightPoints.add(pointsList.get(i));
}
leftSkylinePoints=findSkyline(leftPoints);
rightSkylinePoints=findSkyline(rightPoints);
int minY=1001;
for (int i=0;i<leftSkylinePoints.size();i++){
if (leftSkylinePoints.get(i).y<minY){
minY=leftSkylinePoints.get(i).y;
}
}
for (int i=0;i<rightSkylinePoints.size();i++){
if (rightSkylinePoints.get(i).y>=minY){
rightSkylinePoints.remove(i);
}
}
System.out.println("MINY: "+minY);
System.out.print("Left: ");
for (int i=0;i<leftSkylinePoints.size();i++){
System.out.print("("+leftSkylinePoints.get(i).x+","+leftSkylinePoints.get(i).y+") ");
}
System.out.println();
System.out.print("Right: ");
for (int i=0;i<rightSkylinePoints.size();i++){
System.out.print("("+rightSkylinePoints.get(i).x+","+rightSkylinePoints.get(i).y+") ");
}
System.out.println();
System.out.println();
leftSkylinePoints.addAll(rightSkylinePoints);
return leftSkylinePoints;
}
As you can see point (6,2) appears to be in the skyline but it shouldn't be because it should have been deleted in the second for loop. Does anyone know why this is happening? Thanks!
*For more points I get a lot more that shouldn't be there but for now I want to know about this situation.
**Points are sorted based on their x values (ascending)
Ok, I've understood logic flaw. It is here:
for (int i=0;i<rightSkylinePoints.size();i++){
if (rightSkylinePoints.get(i).y>=minY){
rightSkylinePoints.remove(i);
When you remove a point, the rest is shifted left (as far as I understand remove
sense), so the next (non-treated yet) item gets current index i and is excluded from further treatment.
The simplest solutions - use while
loop and omit incrementing index if removing occurs.
Another method - loop from larger indexes to lower ones (seems that such direction should not break algorithm)
for (int i=rightSkylinePoints.size() -1; i >=0; i--)