Cycle a list from alternating sides
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Cycling a list from alternating sides usually means taking one element from the left, then one from the right, then back to the left, and so on. For example, [1, 2, 3, 4, 5, 6] becomes [1, 6, 2, 5, 3, 4]. The problem is simple once the order is defined clearly, but odd-length lists and ambiguous wording make it easy to implement incorrectly.
Define the ordering rule first
This problem is not the same as rotating or cycling a list by an offset. The intended order is usually:
- first element
- last element
- second element
- second-last element
- and so on
So for an odd-length list:
The middle element appears once at the end because eventually the left and right pointers meet.
Two-pointer solution
The clearest implementation uses one index at the left end and one at the right end.
This runs in linear time and is easy to reason about.
Why the left != right check matters
Without that condition, odd-length lists would duplicate the middle element.
For [1, 2, 3, 4, 5], the final step has left == right == 2, so only 3 should be appended once.
That small condition is the main thing that prevents off-by-one errors in this problem.
A deque version
If you prefer popping from both ends, collections.deque is a natural fit.
This is also linear and expresses the idea directly as alternating removals from both ends.
In-place versus new list
Usually you return a new reordered list. Trying to perform this transformation in place is possible but harder to reason about and rarely worth the complexity unless memory constraints are unusually tight.
For most applications, the extra result list is a small price to pay for correctness and readability, especially compared with debugging a complicated in-place reorder.
Most applications benefit more from clear code than from avoiding one result list allocation.
When the input is not a list
If the input is an arbitrary iterable, convert it first or use a data structure that supports efficient access at both ends. The two-pointer technique assumes indexable sequence behavior.
That keeps the core logic simple.
Practical uses
This pattern appears in:
- coding challenge problems
- UI layout ordering rules
- test-data rearrangement
- simple “outside in” traversal problems
The algorithm itself is straightforward; the important part is being precise about what “alternating sides” means.
Common Pitfalls
A common mistake is treating “cycle” as rotation rather than alternating picks from the ends.
Another mistake is forgetting to handle the middle element correctly in odd-length lists.
A third mistake is writing overly clever slicing logic that becomes harder to verify than a simple two-pointer loop.
Summary
- Alternating sides usually means left, right, next-left, next-right.
- A two-pointer loop is the clearest solution.
- Odd-length lists need a check to avoid duplicating the middle element.
- A
dequeis a nice alternative if you want to remove from both ends. - Clarify the intended order before coding, because the word “cycle” is ambiguous.

