Я прочитал ваш вопрос как: «учитывая некоторое двоичное число с всегда установленными битами, создайте оставшиеся возможные двоичные числа».
Например, для 1xx1: вы хотите: 1001, 1011, 1101, 1111.
Алгоритм O (N) выглядит следующим образом.
Предположим, что биты определены в маске m. У вас также есть хеш h.
Для генерации чисел
counter = 0
for x in 0..n-1:
x' = x | ~m
if h[x'] is not set:
h[x'] = counter
counter += 1
Идея в коде состоит в том, чтобы пройти через все числа от 0 до n-1 и установить предварительно определенные биты в 1. Затем запомните полученное число (если оно еще не запомнено), сопоставив полученное число со значением бегущего счетчика.
Ключи h будут перестановками. В качестве бонуса h [p] будет содержать уникальный номер индекса для перестановки p, хотя он вам не понадобился в исходном вопросе, он может быть полезен.