- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 49 lines of C++ from the credited upstream file 587.cpp.
- The implementation visibly relies on sequence storage.
- 4 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
12class Solution {3 public:4 vector<vector<int>> outerTrees(vector<vector<int>>& trees) {5 vector<vector<int>> hull;6 7 ranges::sort(trees, ranges::less{}, [](const vector<int>& tree) {8 const int x = tree[0];9 const int y = tree[1];10 return pair<int, int>{x, y};11 });12 13 14 for (const vector<int>& tree : trees) {15 while (hull.size() > 1 &&16 cross(hull.back(), hull[hull.size() - 2], tree) > 0)17 hull.pop_back();18 hull.push_back(tree);19 }20 hull.pop_back();21 22 23 for (int i = trees.size() - 1; i >= 0; --i) {24 while (hull.size() > 1 &&25 cross(hull.back(), hull[hull.size() - 2], trees[i]) > 0)26 hull.pop_back();27 hull.push_back(trees[i]);28 }29 30 31 ranges::sort(hull, ranges::less{}, [](const vector<int>& tree) {32 const int x = tree[0];33 const int y = tree[1];34 return pair<int, int>{y, x};35 });36 hull.erase(unique(hull.begin(), hull.end(),37 [](const vector<int>& a, const vector<int>& b) {38 return a[0] == b[0] && a[1] == b[1];39 }),40 hull.end());41 return hull;42 }43 44 private:45 int cross(const vector<int>& p, const vector<int>& q, const vector<int>& r) {46 return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);47 }48};49