Как переместить все нули в правую часть массива, сохранив порядок остальных элементов
Что проверяют
Умеете ли вы решить задачу за один проход без лишней памяти и объяснить сложность, а не только написать работающий код. Следом обычно спрашивают про альтернативы в стиле Python и что будет с False или 0.0 в списке.
Как отвечать
Начните с уточнений: менять список на месте или вернуть новый, какие значения считать нулём. Затем основной вариант, два указателя:
def move_zeros(nums: list) -> None:
write = 0
for read in range(len(nums)):
if nums[read] != 0:
nums[write], nums[read] = nums[read], nums[write]
write += 1Указатель read идёт по всем элементам, write показывает, куда поставить следующий ненулевой. Обмен сохраняет порядок ненулевых, а нули сами оказываются справа. Время O(n), дополнительная память O(1), один проход. Вариант «сначала сдвинуть ненулевые, потом дописать нули» тоже O(n), но проходов два.
Полезно показать и питоничные альтернативы с оценкой:
- новый список:
[x for x in nums if x != 0] + [0] * nums.count(0), O(n) по времени и O(n) по памяти, читается проще всего; - сортировка по ключу:
nums.sort(key=lambda x: x == 0). Работает, потому что сортировка в Python стабильна, но это O(n log n) без причины; - присваивание срезу:
nums[:] = ...меняет исходный объект, если по условию нужен in-place, а решение строит новый список.
Проговорите тесты: пустой список, все нули, ни одного нуля, нули только в конце, один элемент.
Где спотыкаются
Удаляют нули через nums.remove(0) и append(0) прямо в цикле по тому же списку. Итерация пропускает элементы, а каждый remove стоит O(n), итого O(n²).
Пишут nums = new_list внутри функции и считают, что изменили аргумент. Меняется только локальное имя, нужен nums[:].
Не думают о типах: False == 0 в Python истинно, и логические значения тоже уедут вправо. Если их нужно оставить на месте, условие пишут с явной проверкой типа, например x != 0 or isinstance(x, bool).