Ускорение кода Python

Имеется задача. В наличии n разных поддонов. У каждого поддона есть ширина и длинна. Поддон p можно поставить на поддон q, только если p целиком помещается на q. Это означает что длина и ширина первого поддона строго меньше длины и ширины второго поддона. Найдите количество поддонов, которые нельзя поставить ни на один другой поддон. Ввод данных осуществляется следующим образом: первой строкой идет n - число поддонов, а потом на каждой строке отдельно параметры для каждого поддона. Пример ввода:

5

1 1

2 10

2 2

3 6

5 4

Суть вопроса: я написал код, он правильно работает, но не проходит по скорости. Как его можно ускорить?

def compare(lhs, rhs):
    return (lhs[0] < rhs[0] and lhs[1] < rhs[1]) or (lhs[0] < rhs[1] and lhs[1] < rhs[0])


def solve():
    from sys import stdout, stdin
    text = stdin.readlines()
    n = int(text[0])
    boxes, counter, st = tuple(tuple(int(item) for item in text[i].split()) for i in range(1, n + 1)), 0, set()
    for box in boxes:
        if box in st:
            counter += 1
        else:
            for comp in boxes:
                if comp not in st and compare(box, comp):
                    st.add(box)
                    counter += 1
                    break
    stdout.write(str(len(boxes) - counter))


solve()

Ответы (2 шт):

Автор решения: MBo

Отсортировать поддоны по длине по убыванию. Если длина одинаковая, то первым идёт поддон с большей шириной (т.е. ширина - вторичный ключ сортировки).

Первый поддон не ставится на другие. Запомним его как Big, счётчик единица. Пройдём по списку по порядку. Если текущий поддон не ставится на Big, то увеличим счётчик, и текущий становится Big.

Сложность O(nlogn)+O(n)=O(nlogn)

Задача эквивалентна задаче о доминирующем наборе точек (математически - эффективность по Парето)

введите сюда описание изображения

→ Ссылка
Автор решения: Egor Kuts

Мое решение работает за O(nlogn), но все равно не проходит Time Limit. Скорее всего это лучшая сложность и тесты придумали идиоты, но доказать Lower Bound я не в силах

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

//test it out. Think up different edge cases
public class PalletPlacement {

    static int calculate(List<int[]> pallets) {
        int temp;
        int i;
        for(i = 0; i < pallets.size(); i++) {
            if(pallets.get(i)[0] < pallets.get(i)[1]) {
                temp = pallets.get(i)[0];
                pallets.get(i)[0] = pallets.get(i)[1];
                pallets.get(i)[1] = temp;
            }
        }
        int res = 0;
        Collections.sort(pallets, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[0] != o2[0]) {
                    return o1[0] - o2[0];
                }
                return o2[1] - o1[1];
            }
        });
        int[] dp = new int[pallets.size()];
        int max = Integer.MIN_VALUE;
        for(int j = pallets.size() - 1; j >= 0; j--) {
            max = Math.max(max, pallets.get(j)[1]);
            dp[j] = max;
        }
        for(i = 0; i < pallets.size(); i++) {
            int start = i + 1;
            int end = pallets.size() - 1;

            while(start <= end) {
                int middle = start + (end - start) / 2;

                if (pallets.get(middle)[0] > pallets.get(i)[0]) {
                    end = middle - 1;
                } else {
                    start = middle + 1;
                }
            }
            if(start >= dp.length || dp[start] <= pallets.get(i)[1]) {
                res++;
            }

        }
        return res;
    }

    public static void main(String[] args) throws IOException {
        InputStreamReader reader = new InputStreamReader(System.in);
        BufferedReader in = new BufferedReader(reader);
        int n = Integer.parseInt(in.readLine());
        List<int[]> pallets = new ArrayList<>(n);
        for(int i = 0; i < n; i++) {
            String[] split = in.readLine().split(" ");
            int[] temp = new int[2];
            temp[0] = Integer.parseInt(split[0]);
            temp[1] = Integer.parseInt(split[1]);
            pallets.add(temp);
        }
        int res = calculate(pallets);
        System.out.println(res);
    }
}
→ Ссылка