https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/description/

def findMinArrowShots(self, points: List[List[int]]) -> int:
  points.sort(key=lambda x:x[1])

  i = 0
  arrows = 0
  while i < len(points):
      start, end = points[i]
      # overlapping
      while i + 1 < len(points) and end >= points[i+1][0]:
          i += 1
      i += 1
      arrows += 1
      
  return arrows
class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        // sorts points based on increasing order of the end (second) value
        auto compare = [](const vector<int>& a, const vector<int>& b) {
            return a[1] < b[1];
        };

        sort(points.begin(), points.end(), compare);
        
        int i = 0;
        int arrows = 0;
        while (i < points.size()){
            int start = points[i][0];
            int end = points[i][1];
            while (i+1 < points.size() && end >= points[i+1][0]){
                i++;
            }
            arrows++;
            i++;
        }

        return arrows;
    }
};

$Time = O(N *log N)$ because of sorting of the input data.

$Space = O(N)$ or $O(logN)$

The space complexity of the sorting algorithm depends on the implementation of each programming language.

For instance, the list.sort() function in Python is implemented with the Timsort algorithm whose space complexity is O(N).

In Java, the Arrays.sort() is implemented as a variant of quicksort algorithm whose space complexity is O(\log N).