Почему метод 2 быстрее, чем метод 1, даже если метод 2 использует временную сложность O (2n), а метод 1 решает ту же проблему за O (n)

Решал проблему Элемент большинства GFG. У меня была такая же проблема с двумя подходами

Method 1

static int majorityElement1(int a[], int size) {
        HashMap<Integer, Integer> mp = new HashMap<>();
        int count = 0;
        int maxNum = 0;
        for (int i = 0; i < a.length; i++) {
            if (mp.containsKey(a[i])) {
                if (count < mp.get(a[i]) + 1) {
                    count = mp.get(a[i]) + 1;
                    maxNum = a[i];
                }
                mp.replace(a[i], mp.get(a[i]) + 1);
            } else {
                if (count < 1) {
                    count = 1;
                    maxNum = a[i];
                }
                mp.put(a[i], 1);
            }
        }
        return (mp.get(maxNum) > size / 2) ? maxNum : -1;
    }

Method 2

static int majorityElement(int a[], int size) {
        int count = 0;
        int maxNum = 0;
        for (int i = 0; i < a.length; i++) {
            if (count == 0) {
                maxNum = a[i];
                count++;
            } else {
                if (maxNum == a[i]) {
                    count++;
                } else {
                    count--;
                }
            }
        }
        count = 0;
        for (int i = 0; i < a.length; i++) {
            if (a[i] == maxNum) {
                count++;
            }
        }
        return (count > size / 2) ? maxNum : -1;
    }

Даже мыслительный метод 1 решает проблему в На). Компилятор времени временной сложности GFG показывает, что лимит времени превышен. Но он показывает исполнение успешно, когда я использую код метода 2, временная сложность которого равна O (2n). Не могли бы вы помочь мне понять, как это происходит?

временная сложность не означает фактическую скорость выполнения. Это просто способ сравнить алгоритмы, поскольку n становится все больше и больше.

Lino 30.03.2021 11:00
O(2n) == O(n)! Постоянные факторы не учитываются.
Seelenvirtuose 30.03.2021 11:00

и это одна из проблем этой нотации: 100000n хуже, чем 1n, несмотря на такую ​​же сложность (использование HashMap и поиск в нем, безусловно, требует дополнительного времени)

user15244370 30.03.2021 11:45

Как работает второй алгоритм?

k314159 30.03.2021 13:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
40
1

Ответы 1

Обозначение Big O дает вам представление о росте с помощью «некоторого n». Это необходимо для правильного понимания используемых вами алгоритмов.

Учитывая это, вы не видите здесь общей картины. Как только вы знаете, что алгоритм находится в O (n) по сравнению с другим, который находится в O (2n), вы в основном говорите, что оба алгоритма растут с линейной скоростью, на самом деле постоянные коэффициенты поглощаются, поэтому оба они находятся в O ( п). Вы не можете точно знать, с какой скоростью, но вам придется копать больше.

Копать означает начать рассматривать дополнительные детали, такие как:

  • сколько раз мы читаем значение из памяти?
  • сколько обменов мы выполняем?

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

Таким образом, нотация Big-O дает вам представление для грубых сравнений, затем вы должны проанализировать свои входные и выходные данные, чтобы понять, в чем на самом деле происходит рост: вы можете использовать неэффективный алгоритм для сортировки 10 элементов, но вы, возможно, не захотите делать то же самое с 100000.

В Википедии есть очень подробная и исчерпывающая статья здесь. Возможно, вы захотите взглянуть на него, это может помочь вам лучше понять предмет.

Другие вопросы по теме