Запитайте у chatgpt про інструкції байткоду LOOKUPSWITCH та TABLESWITCH
У класичній Java (до Java 7) інструкція switch в байткоді (TABLESWITCH або LOOKUPSWITCH) працювала тільки з типами, які можна привести до int.
Це тому що і TABLESWITCH, і LOOKUPSWITCH фізично вимагають ціле число на вершині стеку.
В Java 7 додали підтримку String — там використовується hashcode String для такої ж імплементації з пошуком по таблиці і подальшої додаткової перевірки по equals на випадок колізій.
«машинний стан» — це дещо дивний спосіб перекласти State Machine. Зазвичай то називають «скінченний автомат» (див. Скінченний автомат ), або якщо вже потрібно робити дослівний переклад, то мало б бути «машина станів»
У Тімсорт так саме як у вас знаходяться піддіапазони з послідовно зростаючими/спадаючими даними, потім вони мерджаться, щоб мінімізувати додаткову пам’ять мердж відбувається тільки при виконанні певних умов щодо розміру цих піддіапазонів. Якщо мердж зараз не є вигідним, піддіапазон додається в стек (щоб не порушити стабільність і зливати тільки суміжні піддіапазони). Якщо діапазони все одно замалі, вони дорощуються до певної мінімальної довжини за допомогою InsertionSort. Для зменшення кількості порівнянь при злитті великих піддіапазонів додатково використовується «галапування» (експоненційний пошук, де крок збільшується на певний фактор, поки не буде «перебор», а потім бінарним діленням в межах останньої «виделки»), щоб швидше знайти голову та хвіст піддіапазонів, які не перекриваються і тому можуть бути просто скопійовані у вихідний масив без додаткових порівнянь, а середня частина, що перекривається у двох піддіапазонах, вже зливається за звичною схемою по одному чемпіону по черзі.
Тобто ця ідея з використанням «хвиль» вже давно опрацьована і оптимальні стратегії в цьому напрямку досліджені і використовуються в стандартних бібліотеках (принаймні в Python та Java саме цей алгоритм використовується для стабільного сортування).
Якщо операція порівняння задорога, то можна або спробувати зробити штучні ключі, які обчислюються один раз для кожного елементу перед сортуванням і порівняння яких для двох елементів дасть той самий результат, що й порівняння самих елементів, і далі вже сортувати ті ключі (вони зберігають індекс оригінального елементу) і отримати відсортований індекс для початкових даних по обраному критерію (можна створити кілька індексів по різним критеріям без тасування самих даних). Другий спосіб — це відсортувати по одному критерію, а потім — по іншому, якщо алгоритм сортування стабільний, то на виході отримуємо сортування по всім зазначеним критеріям (найбільш значущий використовується для сортування останнім).
Зазвичай, якщо порівняння коштують дорого, використовується якийсь з варіантів en.wikipedia.org/wiki/Bucket_sort що дозволяє поділяти на групи, які можна впорядкувати між собою, і подальші порівняння відбуваються лише між елементами в межах однієї групи.
Немає нічого нового під місяцем:
en.wikipedia.org/wiki/Timsort
Невеличкий лайфхак з користання Leetcode:
коли ви вже розв’язали задачу, то можна клікнути на стовпчик тієї діаграми з розподілом по часу чи по пам’яті, і вам буде показано типовий код, який потрапив в цю категорію. Наприклад, кращий за часом виконання код для цієї задачі виглядає так:
var topKFrequent = function(nums, k) { const frequencyMap = nums.reduce((accumulator, curr) => { return accumulator.set(curr, accumulator.get(curr) + 1 || 1); }, new Map()); return Array.from(frequencyMap).sort((a, b) => b[1] - a[1]).slice(0, k).map(elem => elem[0]); };
В Java21 вже можна, додали в JEP_441
openjdk.org/jeps/441