Количество отсортированных массивов длины M, которые можно составить из первых N натуральных чисел

Опубликовано: 22 Сентября, 2022

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

Примеры:

Input: N = 4, M = 2
Output: 10
Explanation: All such possible arrays are {1, 1}, {1, 2}, {1, 2}, {1, 4}, {2, 2}, {2, 3}, {2, 4}, {3, 3}, {3, 4}, {4, 4}.

Input: N = 2, M = 4
Output: 5
Explanation: All such possible arrays are {1, 1, 1, 1}, {1, 1, 1, 2}, {1, 1, 2, 2}, {1, 2, 2, 2}, {2, 2, 2, 2}.

Наивный подход: для каждого числа есть два варианта: его можно взять или оставить. Кроме того, число может быть взято несколько раз.

  • Элементы, которые берутся несколько раз, должны быть последовательными в массиве, так как массив должен быть отсортирован.
  • Если элемент оставлен и перемещен к другому элементу, то этот элемент нельзя взять снова.

Рекурсивный подход:

Левая ветвь указывает, что элемент взят, а правая ветвь указывает, что элемент оставлен и указатель переместился к следующему элементу.

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O(2 N )
Вспомогательное пространство: O(1)

Рекурсивный подход с оптимизацией:

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

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O(2 N )
Вспомогательное пространство: O(1)

Подход динамического программирования. Можно заметить, что эта проблема имеет перекрывающиеся подзадачи и свойство оптимальной подструктуры, т. е. удовлетворяет обоим свойствам динамического программирования. Итак, идея состоит в том, чтобы использовать 2D-таблицу для запоминания результатов во время вызовов функций.

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O(N*M)
Вспомогательное пространство: O(N*M)

Оптимизированный по пространству подход итеративного динамического программирования:

  • Поскольку все элементы доступны столько раз, сколько необходимо, поэтому нет необходимости сохранять значения для предыдущих строк, можно использовать значения из той же строки.
  • Таким образом, одномерный массив можно использовать для сохранения предыдущих результатов.
  • Создайте массив dp размера M , где dp[i] хранит максимальное количество отсортированных массивов размера i , которые могут быть сформированы из чисел в диапазоне [1, N] .

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O(N*M)
Вспомогательное пространство: O(M)