Задача на операцию с битами
Имеется целое число, в котором можно изменить ровно один бит из 0 в 1. Напишите код для определения длины самой длинной последовательности единиц, которая может быть при этом получена.
7К открытий7К показов
Условие задачи
Имеется целое число, в котором можно изменить ровно один бит из 0 в 1. Напишите код для определения длины самой длинной последовательности единиц, которая может быть при этом получена.
Пример:
Ввод: 1775 (или 11011101111).
Вывод: 8.
Решение
Любое целое число может рассматриваться как последовательность чередующихся 1 и 0. Если последовательность 0 имеет длину 1, появляется потенциальная возможность слияния соседних последовательностей 1.
Метод «грубой силы»
Целое число можно преобразовать в массив, отражающий длины последовательностей 0 и 1. При наличии такого массива мы просто перебираем его элементы. Для каждой последовательности 0 рассматривается возможность слияния соседних последовательностей 1, если последовательность 0 имеет длину 1.
Решение получается довольно эффективным. Оно требует затрат времени O(b) и затрат памяти O(b), где b — длина последовательности. Подробнее об оценке сложности алгоритмов вы можете прочитать в нашей статье.
Будьте внимательны с выражением времени выполнения. Например, если сказать, что время выполнения равно О(n), что есть n? Было бы неправильно утверждать, что алгоритм имеет сложность О(целое значение): он имеет сложность О(количество битов). По этой причине, если использование n создает потенциальную неоднозначность, лучше не использовать эту запись, чтобы не путаться самому и не путать интервьюера. Выберите другое имя переменной (мы выбрали b, от слова «bits»).
Возможно ли получить лучший результат? В данном случае читать последовательность приходится всегда, поэтому оптимизировать решение по времени не удастся. С другой стороны, можно сократить затраты памяти.
Оптимальный алгоритм
Чтобы сократить затраты памяти, обратите внимание на то, что нам не нужно постоянно хранить длину каждой последовательности. Она должна храниться столько времени, сколько необходимо для сравнения каждой последовательности 1 с предшествующей ей последовательностью 1.
Следовательно, мы можем ограничиться отслеживанием длин текущей и предыдущей последовательности 1. При обнаружении нулевого бита происходит обновление предыдущей длины previousLength
:
- Если следующий бит содержит 1,
previousLength
присваиваетсяcurrentLength
; - Если следующий бит содержит 0, выполнить слияние последовательностей невозможно, поэтому
previousLength
присваивается 0.
Значение maxLength
обновляется в процессе перебора.
Время выполнения этого алгоритма также равно О(b), но объем дополнительной памяти сокращается до О(1).
Если вы решили данную задачу, попробуйте реализовать функцию, определяющую количество битов, которое необходимо изменить, чтобы из целого числа А получить целое число B. Решение найдете здесь.
7К открытий7К показов