- Translate each rule into one explicit state update.
- Maintain the invariant after every processed item.
- Return the accumulated state once all relevant input has been handled.
Code notes
- 105 lines of C++ from the credited upstream file 1924.cpp.
- The implementation visibly relies on sequence storage.
- 1 loop block detected.
Complexity
Count the number and nesting of passes over the input, then include the maintained containers in the memory estimate.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1struct Point {2 double x;3 double y;4 Point(double x, double y) : x(x), y(y) {}5};6 7struct Disk {8 Point center;9 double radius;10 Disk(const Point& center, double radius) : center(center), radius(radius) {}11};12 13class Solution {14 public:15 vector<double> outerTrees(vector<vector<int>>& trees) {16 vector<Point> points;17 for (int i = 0; i < trees.size(); ++i)18 points.emplace_back(trees[i][0], trees[i][1]);19 Disk disk = welzl(points, 0, {});20 return {disk.center.x, disk.center.y, disk.radius};21 }22 23 private:24 25 26 27 Disk welzl(const vector<Point>& points, int i, vector<Point> planePoints) {28 if (i == points.size() || planePoints.size() == 3)29 return trivial(planePoints);30 Disk disk = welzl(points, i + 1, planePoints);31 if (inside(disk, points[i]))32 return disk;33 return welzl(points, i + 1, addPlanePoint(planePoints, points[i]));34 }35 36 vector<Point> addPlanePoint(const vector<Point>& planePoints,37 const Point& point) {38 vector<Point> newPlanePoints(planePoints);39 newPlanePoints.push_back(point);40 return newPlanePoints;41 }42 43 Disk trivial(const vector<Point>& planePoints) {44 if (planePoints.empty())45 return Disk(Point(0, 0), 0);46 if (planePoints.size() == 1)47 return Disk(Point(planePoints[0].x, planePoints[0].y), 0);48 if (planePoints.size() == 2)49 return getDisk(planePoints[0], planePoints[1]);50 51 Disk disk01 = getDisk(planePoints[0], planePoints[1]);52 if (inside(disk01, planePoints[2]))53 return disk01;54 55 Disk disk02 = getDisk(planePoints[0], planePoints[2]);56 if (inside(disk02, planePoints[1]))57 return disk02;58 59 Disk disk12 = getDisk(planePoints[1], planePoints[2]);60 if (inside(disk12, planePoints[0]))61 return disk12;62 63 return getDisk(planePoints[0], planePoints[1], planePoints[2]);64 }65 66 67 Disk getDisk(const Point& A, const Point& B) {68 const double x = (A.x + B.x) / 2;69 const double y = (A.y + B.y) / 2;70 return Disk(Point(x, y), distance(A, B) / 2);71 }72 73 74 Disk getDisk(const Point& A, const Point& B, const Point& C) {75 76 Point mAB((A.x + B.x) / 2, (A.y + B.y) / 2);77 Point mBC((B.x + C.x) / 2, (B.y + C.y) / 2);78 79 80 const double slopeAB = (B.y - A.y) / (B.x - A.x);81 const double slopeBC = (C.y - B.y) / (C.x - B.x);82 const double perpSlopeAB = -1 / slopeAB;83 const double perpSlopeBC = -1 / slopeBC;84 85 86 const double x =87 (perpSlopeBC * mBC.x - perpSlopeAB * mAB.x + mAB.y - mBC.y) /88 (perpSlopeBC - perpSlopeAB);89 const double y = perpSlopeAB * (x - mAB.x) + mAB.y;90 Point center(x, y);91 return Disk(center, distance(center, A));92 }93 94 95 bool inside(Disk disk, Point point) {96 return disk.radius > 0 && distance(disk.center, point) <= disk.radius;97 }98 99 double distance(Point A, Point B) {100 const double dx = A.x - B.x;101 const double dy = A.y - B.y;102 return sqrt(dx * dx + dy * dy);103 }104};105