Алгоритмика: метод “словарь” – записываем значения как ключ элемента массива
Glossary overview

Алгоритмика: метод “словарь” – записываем значения как ключ элемента массива

Что такое метод словарь?

Словарь это структура “ключ -> значение”.
В PHP это обычный ассоциативный массив:

    • ключ: строка или число (но числа часто становятся строками, если ты сам приводишь)
    • значение: что угодно (bool, int, массив, объект)

    Идея: по ключу можно проверять/доставать очень быстро (в среднем O(1)).

    Зачем он нужен

    Чтобы не делать “поиск внутри массива” каждый раз.
    Потому что поиск через цикл обычно O(n).
    А если ты делаешь это внутри другого цикла, привет O(n^2).

      Словарь часто превращает задачу из “долго и больно” в “один проход”.

      Два базовых паттерна

        1. Set (множество): “видел/не видел”. Тут значение не важно, обычно true.

        Пример: убрать дубликаты / проверить дубликаты.

        Идея: ключи это значения. Если ключ уже есть, значит повтор.

        function uniqueValues(array $arr): array {
            $seen = [];
            $result = [];
        
            foreach ($arr as $x) {
                $key = (string)$x;          // ключ в словаре
                if (isset($seen[$key])) {
                    continue;               // уже было, пропускаем
                }
        
                $seen[$key] = true;         // помечаем
                $result[] = $x;             // сохраняем в результат
            }
        
            return $result;
        }
        
        print_r(uniqueValues([5, 2, 2, 9, 5, 1]));
        // [5, 2, 9, 1]

        Что тут важно:

        • $seen это “множество”
        • isset($seen[$key]) это проверка “я это уже видел?”
        • порядок сохраняется (потому что мы складываем в $result по ходу)

        2. Counter (счетчик): “сколько раз встречалось”. Тут значение – число.

        function countFreq(array $arr): array {
            $count = [];
        
            foreach ($arr as $x) {
                $key = (string)$x;
                $count[$key] = ($count[$key] ?? 0) + 1;
            }
        
            return $count;
        }
        
        print_r(countFreq([2, 2, 3, 10, 10, 10]));
        // ['2' => 2, '3' => 1, '10' => 3]

        Фишка строки:

        ($count[$key] ?? 0) + 1
        • если ключа нет, берем 0
        • иначе берем текущее значение
        • плюс 1

        Типовые задачи, которые решаются словарем

          • Two Sum (пара с суммой) за O(n)
          • Частоты слов/чисел (самое частое)
          • Дубликаты
          • Пересечение массивов
          • Разница множеств
          • Анаграммы (считаем буквы)

          Задача: найти элементы, которые есть во всех массивах.

            Правильная логика:

            • для каждого массива считаем уникальные элементы (чтоб дубли внутри массива не ломали счетчик)
            • увеличиваем счетчик “в скольких массивах встретилось число”
            • в конце берем те, у кого счетчик == кол-во массивов
            <?php
            
            // Пересечение всех массивов: вернуть числа, которые есть в КАЖДОМ массиве (без дублей)
            function intersectionAll(array $arrays): array {
                if (empty($arrays)) return [];
            
                $dict = [];                 // число => сколько массивов его содержат
                $total = count($arrays);
            
                foreach ($arrays as $arr) {
                    // защита от дублей внутри одного массива
                    $seenInThisArray = [];
            
                    foreach ($arr as $x) {
                        $key = (string)$x;
                        if (isset($seenInThisArray[$key])) continue;
            
                        $seenInThisArray[$key] = true;
                        $dict[$key] = ($dict[$key] ?? 0) + 1;
                    }
                }
            
                $result = [];
                foreach ($dict as $key => $count) {
                    if ($count === $total) {
                        $result[] = (int)$key; // если нужны числа
                    }
                }
            
                return $result;
            }
            
            // Пример вызова:
            $arrays = [
                [1, 2, 2, 3, 10],
                [2, 2, 3, 4, 10, 10],
                [0, 2, 3, 5, 10],
            ];
            
            print_r(intersectionAll($arrays));
            // Ожидаемо: Array ( [0] => 2 [1] => 3 [2] => 10 )
            
            // Еще пример:
            $arrays2 = [
                [7, 7, 8, 9],
                [6, 7, 8],
                [7, 8, 10],
            ];
            
            print_r(intersectionAll($arrays2));
            // Ожидаемо: Array ( [0] => 7 [1] => 8 )

            Такой же подход использовал тут https://syntaxsteps.com/guide/php-zadacha-analiz-teksta.