When is copying a linked chain into an array the better symmetry check than the O(1)-space one?
answer
- both versions are linear in time
- what does the extra space buy
- who else can see the chain mid-check
- the restore path is the bug surface
- memory ceiling versus review risk
basics
~20 sCopy when the chain is shared or the routine must survive many maintainers: O(n) space buys a check that mutates nothing and has no restore path to forget. Choose the in-place version when memory is the binding constraint.
solid answer
~50 sBoth are O(n) time, so the decision is never about speed. The in-place split-reverse-compare buys O(1) extra space by rewiring the caller's links, which brings three liabilities: a restore that must run on every exit path including errors, a window in which a shared structure is briefly invalid to any other reader, and code that no reviewer can verify at a glance. Copying the values into an array costs O(n) space and eliminates all three. I decide on the workload: unbounded chain length, a hard memory ceiling across a fleet, or a hot path the routine owns outright argues for in-place; anything the chain is shared with, anything reentrant or concurrent, and anything a rotating team maintains argues for the copy. In an interview I present the in-place version, because that is what is being tested, and then say where I would actually ship the other one.
go deeper
Know that both approaches are linear in time and that the difference is extra space: one copies the values out, the other rewires the chain and then has to put it back.
Explain the cleanup obligation the in-place version carries and why the copy has none, and give both space bounds without hedging.
Argue from the workload: chain length, who else holds a reference, whether an early exit or an error can skip the restore, and what the clever version costs at review time.
Own the standard rather than the instance — state when constant space is worth a briefly invalid shared structure, write that rule down for the team, and consider whether the representation itself should change.
## The two candidates, stated fairly **Copy out.** Walk the chain once, collecting values into a growable array. Compare with converging indices. O(n) time, O(n) extra space. The chain is never touched. **In place.** Split at the middle, reverse the back half, compare in lockstep, reverse the back half again to restore. O(n) time, O(1) extra space. The chain is edited and then repaired. Note what is *not* on the table: a time difference. Both are linear, both make a small constant number of passes. Anyone arguing this trade on speed has misread it. ## What the constant space actually costs 1. **A cleanup obligation on every exit path.** The mismatch return, the loop's normal end, and any error raised while comparing two values all have to leave the chain repaired. The version people write first repairs it on exactly one of those paths. 2. **A window of invalidity.** Between the reversal and its undo, the structure is not what its owner believes it is. If any other party can look during that window — an iterator held elsewhere, a comparator that calls back into user code, another thread — it observes corruption, and no amount of restoring afterwards helps. 3. **Review cost.** The in-place version is three subroutines' worth of pointer surgery whose correctness rests on invariants that do not appear in the code. The copy version is a loop and a comparison. On a team where the second-least-experienced person will one day change this function under time pressure, that difference is a real, ongoing expense. ## What the linear space actually costs Be equally honest in the other direction. "O(n) space" sounds severe and often is not: the array holds one value or one reference per node, on a structure that already pays a link per node. The overhead can be a fraction of the structure being examined. It becomes serious when - the chain length is unbounded and driven by external input, - many such checks run at once, so the peak is a multiple of one array, - the environment has a hard per-process or per-device memory ceiling, or - allocation itself is the expensive thing in that path — an allocation on a hot path can cost more than the pointer surgery it replaces. That last one is why "constant space" sometimes wins on *latency* rather than on memory. ## The decision, as a rule you can hand to a team Use the non-mutating copy by default. Reach for the in-place version only when all of the following hold, and write down that they hold: - The routine owns the chain for the duration; nothing else can observe it. - The path is hot enough or the memory ceiling tight enough that O(n) auxiliary space is genuinely a problem, measured rather than assumed. - The restore is unconditional — no `return` inside the mutating region, and errors are covered. Writing the rule down is the principal-level move. Left to individual judgment, every author re-derives the trade from scratch, and half of them re-derive it as "constant space is better, obviously", which is how a query that silently mutates its input reaches production. ## The interview version of the same question The loop is testing whether you know the in-place trick, so produce it. But produce it with the trade attached: one sentence for the array baseline to establish you have a correct, simple answer; the in-place construction as the main answer; then the caveat about the mutation window and the restore. Candidates who only know the trick sound identical to candidates who understand it right up to the moment the interviewer asks "any downside?" — and that question is the entire point of asking. A fourth position is worth having ready: for a structure that is examined this way often, the right move may be neither, but a change of representation — keep the sequence in a form with random access, or maintain the symmetry answer incrementally as elements are appended. Redesigning the input away from a singly linked chain is frequently the cheapest fix available, and noticing that is a different skill from executing either algorithm.
- In an interview, which of the two do you present first?Name the array version in one sentence to establish a correct baseline, then build the constant-space one, because that is what the question is testing. Close on the trade — constant space costs you a mutation window and a cleanup path — which is what separates a candidate who memorised the trick from one who understands its price. Leading with the array version and stopping there reads as not knowing the trick.
- Is O(n) extra space really a meaningful cost for this check?It depends on what a node holds and how the routine is used. One value or reference per node, on a structure that already pays a link per node, is often a small fraction of what is already allocated. It turns serious when the length is unbounded and externally driven, when many checks run at once so the peak multiplies, when a hard memory ceiling applies, or when the allocation itself is the latency cost on a hot path.
- What would make you reject the in-place version outright?Any possibility that another party observes the chain during the check — a comparator that calls back into user code, an iterator held elsewhere, a concurrent reader — or an error that can escape before the restore runs. Constant space is not worth a shared structure that is briefly invalid. I would also reject it in code a rotating team maintains, where the clever version is one careless edit away from a silent mutation bug.
saying these in an interview costs you the question
- Says the in-place version is always the better answer
- Ignores that the copy version mutates nothing
- Treats O(n) extra space as automatically disqualifying
- Claims the two differ in time complexity
- Cannot name a case where the copy is what ships