Разбор задачи: Подсчет битов

Предложенный нами код решения:

def count_bits(n):
    """
    Возвращает список, в котором для каждого числа i от 0 до n указано количество единиц в его двоичном представлении.

    :param n: Целое число
    :return: Список длиной n + 1, где каждый элемент соответствует числу единиц в двоичном представлении i
    """
    ans = [0] * (n + 1)
    for i in range(1, n + 1):
        ans[i] = ans[i >> 1] + (i & 1)
    return ans

1. Аргументы и результат

  • Вход: Целое число n, для которого нужно вычислить количество единиц в двоичном представлении всех чисел от 0 до n.
  • Выход: Список ans длиной n + 1, где элемент ans[i] равен количеству единиц в двоичном представлении числа i.

2. Инициализация списка

ans = [0] * (n + 1)
  • Создаём список ans длиной n + 1, изначально заполненный нулями.
  • Элемент ans[0] уже корректен, так как число 0 в двоичной записи содержит 0 единиц.

3. Основной цикл

for i in range(1, n + 1):
    ans[i] = ans[i >> 1] + (i & 1)

Этот цикл заполняет список ans для всех чисел от 1 до n. Разберём шаги:

  1. i >> 1:
    • Это побитовый сдвиг числа i вправо на 1 бит.
    • Сдвиг эквивалентен делению числа на 2 с отбрасыванием остатка.
    • Пример: для i = 5 (в двоичной системе 101), i >> 1 даст 2 (в двоичной системе 10).
  2. ans[i >> 1]:
    • Значение для числа i можно вычислить на основе числа i // 2, так как они имеют почти одинаковое двоичное представление (различие только в последнем бите).
  3. i & 1:
    • Это побитовая операция "И" с числом 1, которая проверяет, является ли последний бит числа i равным 1.
    • Если последний бит равен 1, добавляем единицу к значению ans[i >> 1].
  4. Суммирование:
    • ans[i] = ans[i >> 1] + (i & 1)
    • Количество единиц в числе i равно количеству единиц в числе i // 2 плюс 1 (если последний бит равен 1).

4. Пример выполнения

Рассмотрим выполнение функции для n = 5:

  • Итерация 1: i = 1
    • i >> 1 = 0, i & 1 = 1
    • ans[1] = ans[0] + 1 = 0 + 1 = 1
  • Итерация 2: i = 2
    • i >> 1 = 1, i & 1 = 0
    • ans[2] = ans[1] + 0 = 1 + 0 = 1
  • Итерация 3: i = 3
    • i >> 1 = 1, i & 1 = 1
    • ans[3] = ans[1] + 1 = 1 + 1 = 2
  • Итерация 4: i = 4
    • i >> 1 = 2, i & 1 = 0
    • ans[4] = ans[2] + 0 = 1 + 0 = 1
  • Итерация 5: i = 5
    • i >> 1 = 2, i & 1 = 1
    • ans[5] = ans[2] + 1 = 1 + 1 = 2

Результат: [0, 1, 1, 2, 1, 2]

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии