Ваше время работы все еще равно O (n), поэтому я не вижу, что с этим есть какие-либо проблемы.
Концептуально вы можете разделить список на две части: часть перед возвращаемым узлом и часть после. Одна из этих частей должна быть пройдена дважды. Ваша реализация выбрала первое, что не требует дополнительного использования памяти (кроме пары временных переменных).
Кроме того, вы можете создать стек, просмотреть список и поместить каждый элемент в стек, а затем вытолкнуть n элементов. Тогда вы дважды пройдете конец списка, а не начало. Недостатком является то, что список хранится в памяти дважды. (Вы могли бы сделать стек немного умнее, только сохраняя n элементов и удаляя их из нижней части стека при добавлении новых; тогда вы используете только достаточно места для хранения n узлов.)
Я предполагаю, что вы не можете уничтожить список, перевернув его на месте. Тогда это постоянная память, все еще O (n), все еще идущая конец списка дважды.