Получить самый частый элемент в массиве

Я пытался оптимизировать это:

const NUMBERS = [2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 9];

const getMode = (arr) => arr
    .sort(
      (a, b) =>
        arr.reduce((acu, cur) => (cur === a ? (acu += 1) : cur)) -
        arr.reduce((acu, cur) => (cur === b ? (acu += 1) : cur))
    )
    .pop();

console.log(getMode(NUMBERS));

Я тоже думал об этом:

const NUMBERS = [2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 9];

const mode = (arr) => arr
    .sort(
      (a, b) =>
        arr.filter((v) => v === a).length - arr.filter((v) => v === b).length
    )
    .pop();
    
console.log(mode(NUMBERS))

Как вы думаете, что можно улучшить?

3 ответа
3

Чтобы повысить производительность, вы можете уменьшить сложность кода.

В настоящее время сложность ваших подходов O (n² log (n)) как sort функция O (п журнал (п)) и на каждой итерации вы используете filter или же reduce который имеет сложность На).

Я могу предложить один подход, при котором вам не нужно сортировать элементы, поэтому сложность метода будет На) при использовании V8 Движок JavaScript (для дополнительной информации) иначе O (п журнал (п)). Оцените этот подход:

const NUMBERS = [2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 9];

const getMode = (arr) => {

  let [maxFreq, result] = [-1, -1];
        
  arr.reduce((acu, cur) => {
                  acu.set(cur, (acu.has(cur) ? acu.get(cur) : 0)+1)
                  return acu;
                 }, new Map())
            .forEach((value, key) => {
                if(value > maxFreq){
                  maxFreq = value;
                  result = key;
                }
              });
  
  return result;
    
 }

console.log(getMode(NUMBERS))

  • Да … @PavloSlavynskyy … спасибо, что поправили!

    — HandsomeCoder

  • 2

    @PavloSlavynskyy согласно этому (stackoverflow.com/questions/33611509/…) в V8 JavaScript Engine временная сложность поиска и поиска равна O (1)

    — HandsomeCoder

Я изменил ответ HandsomeCoder.

На самом деле это O (n), потому что доступ к объекту — O (1)

const NUMBERS = [2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 9];

function getMode(array) {
    function buildFrequencyMap(array) {
        return array.reduce((acu, number) => {
            acu[number] = acu[number] !== undefined ? acu[number] + 1 : 0
            return acu;
        }, {})
    }

    function maxFrequency(frequencyMap) {
        let maxFreq = -1, result = -1

        Object.entries(frequencyMap).forEach(([key, value]) => {
            if(value > maxFreq){
                maxFreq = value;
                result = key;
            }
        });

        return result
    }

    const frequencyMap = buildFrequencyMap(array)

    return maxFrequency(frequencyMap);
}

console.log(getMode(NUMBERS))

    Сортировать!

    Никогда не используйте сортировку для получения максимума или минимума. Сортировка используется только для упорядочивания всех элементов в массиве.

    Если вам нужен максимум в массиве, вы можете использовать Math.max(...[1,2,3,4,5,6,5,4,3,2]) выражает 6.

    Если вам нужно связанное значение, связанное с максимальным или минимальным значением, вам потребуется выполнить итерацию вручную, сохраняя максимальное значение и связанные данные по мере нахождения новых значений.

    Переписать

    В этом примере проверяется количество значений по сравнению с макс. max и сохраните максимальное количество и значение maxVal подсчитанной стоимости

    Для подсчета значений он использует карту, которая использует хеш-карту и $ O (1) $ для поиска, который сделает функцию $ O (п) $

    function getMode(data) {
        var max = -Infinity, maxVal, counts = new Map(), c;
        for (const v of data) {
            c = ++(counts.get(v) ?? (counts.set(v, c = {count: 0}), c)).count;
            [max, maxVal] = c > max ? [c, v] : [max, maxVal];
        }
        return maxVal;
    }
    
    console.log(getMode([2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 9]))

    Вы также можете проверить, больше ли max, чем (n / 2), и выйти, как если бы счетчик больше половины элементов, значение должно быть наиболее частым.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *