How do you detect whether a linked list contains a cycle, and why does the two pointer method work?
Give two pointers the same starting node and move them at different speeds: one step at a time and two steps at a time. If the list has no cycle, the fast pointer reaches the end and the loop ends. If it does have a cycle, the fast pointer gains on the slow one and eventually they meet at the same node.
The reasoning is a chase argument. Once both pointers are inside the cycle, the fast pointer moves one node further around the loop for every single step the slow pointer takes. A gap that is a multiple of the cycle length can never be closed by a whole number of single steps, so the fast pointer must lap the slow one and catch it. Since the cycle has finite length, the catch happens after at most one lap.
The alternative is the set approach: walk the list, remember every node you have seen, and report a cycle when you meet one twice. It is simpler to write and it also gives you the entry point for free, but it costs linear space, whereas the two pointer method uses constant space.
The trade-off to name is that the fast pointer needs both a current and a next check. If you advance it by two without first confirming that its next node exists, you get an attribute error on the last node. So the loop condition has to test that the fast pointer and its successor are both present, which is why the condition looks slightly more careful than the naive version you might first write.