There are some trees, where each tree is represented by (x,y) coordinate in a two-dimensional garden. Your job is to fence the entire garden using the minimum length of rope as it is expensive. The garden is well fenced only if all the trees are enclosed. Your task is to help find the coordinates of trees which are exactly located on the fence perimeter.
/** * Definition for a point. * class Point { * int x; * int y; * Point() { x = 0; y = 0; } * Point(int a, int b) { x = a; y = b; } * } */classSolution {publicList<Point> outerTrees(Point[] points) {if (points.length<3) {returnArrays.asList(points); }Point startPoint = points[0];int startIndex =0;// Find the leftmost point as the start pointfor (int i =1; i <points.length; i++) {if (points[i].x<startPoint.x) { startPoint = points[i]; startIndex = i; } }// Use Set because Gift Wrapping Algorithm may try to insert dupilcate valueSet<Point> res =newHashSet();List<Point> collinearPoints =newArrayList();res.add(startPoint);Point curPoint = startPoint;int curIndex = startIndex;while (true) {Point nextPoint = points[0];int nextIndex =0;for (int i =1; i <points.length; i++) {if (curIndex == i) continue;int crossProduct =getCrossProduct(curPoint, nextPoint, points[i]);// if crossProduct > 0, points[i] is on the left of line curPoint-nextPointif (crossProduct >0) { nextPoint = points[i]; nextIndex = i;// Clear collinearPoints because we change the nextPointcollinearPoints.clear(); }// if crossProduct = 0, points[i] is collinear with curPoint and nextPointelseif (crossProduct ==0) {// Update nextPoint with points[i] is points[i] is further from curPointif (getDistance(curPoint, points[i])>getDistance(curPoint, nextPoint)) {collinearPoints.add(nextPoint); nextPoint = points[i]; nextIndex = i; }// If nextPoint is on the boundary of convex hull// then all points in collinear points will be also on boundary.else {collinearPoints.add(points[i]); } } }for (Point point : collinearPoints) {res.add(point); }// If nextPoint is the same as startPoint, we have formed an envelope and it is done.if (nextPoint == startPoint) {break; }// Add nextPoint to the result and set curPoint as nextPointres.add(nextPoint); curPoint = nextPoint; curIndex = nextIndex; }returnnewArrayList<>(res); }publicintgetCrossProduct(Point A,Point B,Point C) {int ABx =B.x-A.x;int ABy =B.y-A.y;int ACx =C.x-A.x;int ACy =C.y-A.y;return ABx * ACy - ABy * ACx; }publicintgetDistance(Point p1,Point p2) {return (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y); }}