Another method, which I find more clear, is to build a new list and prepend nodes one by one to it. It has the same time and space complexities, but it’s easier to reason through.
static ListNode *reverse(ListNode *head) {
ListNode dummy(0);
while (head != nullptr) {
auto next = head->next;
head->next = dummy.next;
dummy.next = head;
head = next;
}
return dummy.next;
}